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 07/15] ASoC: rt5677: Enable jack detect while DSP is running
Date: Fri,  6 Sep 2019 12:46:29 -0700	[thread overview]
Message-ID: <20190906194636.217881-8-cujomalainey@chromium.org> (raw)
In-Reply-To: <20190906194636.217881-1-cujomalainey@chromium.org>

From: Ben Zhang <benzh@chromium.org>

Before a hotword is detected, GPIO1 pin is configured as IRQ
output so that jack detect works. When a hotword is detected,
the DSP firmware configures the GPIO1 pin as GPIO1 and
drives a 1. rt5677_irq() is called after a rising edge on
the GPIO1 pin, due to either jack detect event or hotword
event, or both. All possible events are checked and handled
in rt5677_irq() where GPIO1 pin is configured back to IRQ
output if a hotword is detected.

Signed-off-by: Ben Zhang <benzh@chromium.org>
Signed-off-by: Curtis Malainey <cujomalainey@chromium.org>
---
 sound/soc/codecs/rt5677.c | 64 +++++++++++++++++++++++++++++----------
 1 file changed, 48 insertions(+), 16 deletions(-)

diff --git a/sound/soc/codecs/rt5677.c b/sound/soc/codecs/rt5677.c
index 9cdfe7d488fe..8f5e4882120c 100644
--- a/sound/soc/codecs/rt5677.c
+++ b/sound/soc/codecs/rt5677.c
@@ -312,6 +312,8 @@ static bool rt5677_volatile_register(struct device *dev, unsigned int reg)
 	case RT5677_IRQ_CTRL1:
 	case RT5677_IRQ_CTRL2:
 	case RT5677_GPIO_ST:
+	case RT5677_GPIO_CTRL1: /* Modified by DSP firmware */
+	case RT5677_GPIO_CTRL2: /* Modified by DSP firmware */
 	case RT5677_DSP_INB1_SRC_CTRL4:
 	case RT5677_DSP_INB2_SRC_CTRL4:
 	case RT5677_DSP_INB3_SRC_CTRL4:
@@ -787,8 +789,11 @@ static unsigned int rt5677_set_vad_source(
 	regmap_update_bits(rt5677->regmap, RT5677_DSP_INB_CTRL1,
 		RT5677_IB01_SRC_MASK, 4 << RT5677_IB01_SRC_SFT);
 
-	/* IRQ Source of VAD Jack Detection = enable */
-	regmap_write(rt5677->regmap, RT5677_IRQ_CTRL2, 0x4000);
+	/* VAD/SAD is not routed to the IRQ output (i.e. MX-BE[14] = 0), but it
+	 * is routed to DSP_IRQ_0, so DSP firmware may use it to sleep and save
+	 * power. See ALC5677 datasheet section 9.17 "GPIO, Interrupt and Jack
+	 * Detection" for more info.
+	 */
 
 	/* Enable Gating Mode with MCLK = enable */
 	regmap_update_bits(rt5677->regmap, RT5677_DIG_MISC, 0x1, 0x1);
@@ -924,15 +929,15 @@ static int rt5677_set_dsp_vad(struct snd_soc_component *component, bool on)
 	if (on && !activity) {
 		activity = true;
 
-		/* Set GPIO1 as an output pin driving a 0. Firmware will
-		 * raise GPIO1 upon hotword detect.
+		/* Before a hotword is detected, GPIO1 pin is configured as IRQ
+		 * output so that jack detect works. When a hotword is detected,
+		 * the DSP firmware configures the GPIO1 pin as GPIO1 and
+		 * drives a 1. rt5677_irq() is called after a rising edge on
+		 * the GPIO1 pin, due to either jack detect event or hotword
+		 * event, or both. All possible events are checked and handled
+		 * in rt5677_irq() where GPIO1 pin is configured back to IRQ
+		 * output if a hotword is detected.
 		 */
-		regmap_update_bits(rt5677->regmap, RT5677_GPIO_CTRL2,
-			RT5677_GPIO1_DIR_MASK |	RT5677_GPIO1_OUT_MASK |
-			RT5677_GPIO1_P_MASK, RT5677_GPIO1_DIR_OUT |
-			RT5677_GPIO1_OUT_LO | RT5677_GPIO1_P_NOR);
-		regmap_update_bits(rt5677->regmap, RT5677_GPIO_CTRL1,
-			RT5677_GPIO1_PIN_MASK, RT5677_GPIO1_PIN_GPIO1);
 
 		rt5677_set_vad_source(component);
 		rt5677_set_dsp_mode(component, true);
@@ -952,6 +957,8 @@ static int rt5677_set_dsp_vad(struct snd_soc_component *component, bool on)
 	} else if (!on && activity) {
 		activity = false;
 
+		/* Don't turn off the DSP while handling irqs */
+		mutex_lock(&rt5677->irq_lock);
 		/* Set DSP CPU to Stop */
 		regmap_update_bits(rt5677->regmap, RT5677_PWR_DSP1,
 			RT5677_PWR_DSP_CPU, RT5677_PWR_DSP_CPU);
@@ -959,13 +966,12 @@ static int rt5677_set_dsp_vad(struct snd_soc_component *component, bool on)
 
 		/* Disable and clear VAD interrupt */
 		regmap_write(rt5677->regmap, RT5677_VAD_CTRL1, 0x2184);
-		regmap_update_bits(rt5677->regmap, RT5677_IRQ_CTRL2,
-			0xF000, 0x0000);
 
 		/* Set GPIO1 pin back to be IRQ output for jack detect */
 		regmap_update_bits(rt5677->regmap, RT5677_GPIO_CTRL1,
 			RT5677_GPIO1_PIN_MASK, RT5677_GPIO1_PIN_IRQ);
 
+		mutex_unlock(&rt5677->irq_lock);
 	}
 
 	return 0;
@@ -5273,6 +5279,28 @@ static const struct rt5677_irq_desc rt5677_irq_descs[] = {
 	},
 };
 
+bool rt5677_check_hotword(struct rt5677_priv *rt5677)
+{
+	int reg_gpio;
+
+	if (!rt5677->is_dsp_mode)
+		return false;
+
+	if (regmap_read(rt5677->regmap, RT5677_GPIO_CTRL1, &reg_gpio))
+		return false;
+
+	/* Firmware sets GPIO1 pin to be GPIO1 after hotword is detected */
+	if ((reg_gpio & RT5677_GPIO1_PIN_MASK) == RT5677_GPIO1_PIN_IRQ)
+		return false;
+
+	/* Set GPIO1 pin back to be IRQ output for jack detect */
+	regmap_update_bits(rt5677->regmap, RT5677_GPIO_CTRL1,
+			RT5677_GPIO1_PIN_MASK, RT5677_GPIO1_PIN_IRQ);
+
+	rt5677_spi_hotword_detected();
+	return true;
+}
+
 static irqreturn_t rt5677_irq(int unused, void *data)
 {
 	struct rt5677_priv *rt5677 = data;
@@ -5281,9 +5309,6 @@ static irqreturn_t rt5677_irq(int unused, void *data)
 
 	mutex_lock(&rt5677->irq_lock);
 
-	if (rt5677->dsp_vad_en)
-		rt5677_spi_hotword_detected();
-
 	/*
 	 * Loop to handle interrupts until the last i2c read shows no pending
 	 * irqs. The interrupt line is shared by multiple interrupt sources.
@@ -5321,7 +5346,13 @@ static irqreturn_t rt5677_irq(int unused, void *data)
 				reg_irq ^= rt5677_irq_descs[i].polarity_mask;
 			}
 		}
-		if (!irq_fired)
+
+		/* Exit the loop only when we know for sure that GPIO1 pin
+		 * was low at some point since irq_lock was acquired. Any event
+		 * after that point creates a rising edge that triggers another
+		 * call to rt5677_irq().
+		 */
+		if (!irq_fired && !rt5677_check_hotword(rt5677))
 			goto exit;
 
 		ret = regmap_write(rt5677->regmap, RT5677_IRQ_CTRL1, reg_irq);
@@ -5332,6 +5363,7 @@ static irqreturn_t rt5677_irq(int unused, void *data)
 		}
 	}
 exit:
+	WARN_ON_ONCE(loop == 20);
 	mutex_unlock(&rt5677->irq_lock);
 	if (irq_fired)
 		return IRQ_HANDLED;
-- 
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:53 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 ` Curtis Malainey [this message]
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 ` [alsa-devel] [RFC 13/15] ASoC: rt5677: Disable irq at suspend Curtis Malainey
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-8-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).