* [PATCH] ASoC: nau8825: Modify power management and add interrupt wakeup
@ 2016-01-08 7:11 John Hsu
2016-01-08 13:13 ` Mark Brown
0 siblings, 1 reply; 5+ messages in thread
From: John Hsu @ 2016-01-08 7:11 UTC (permalink / raw)
To: broonie
Cc: alsa-devel, anatol.pomozov, YHCHuang, John Hsu, lgirdwood, benzh,
CTLIN0, mhkuo, yong.zhi
1. Enhance codec suspend and resume sequence
2. Add interrupt wakeup function
Signed-off-by: John Hsu <KCHSU0@nuvoton.com>
---
sound/soc/codecs/nau8825.c | 86 ++++++++++++++++++++++++++++++++++++++++++----
sound/soc/codecs/nau8825.h | 2 ++
2 files changed, 81 insertions(+), 7 deletions(-)
diff --git a/sound/soc/codecs/nau8825.c b/sound/soc/codecs/nau8825.c
index 504c969..9a02d05 100644
--- a/sound/soc/codecs/nau8825.c
+++ b/sound/soc/codecs/nau8825.c
@@ -543,6 +543,45 @@ int nau8825_enable_jack_detect(struct snd_soc_codec *codec,
}
EXPORT_SYMBOL_GPL(nau8825_enable_jack_detect);
+/**
+ * nau8825_init_wakeup - set wakeup capability for codec
+ *
+ * @codec: codec device component
+ *
+ * After this function done, codec can support system wakeup by button.
+ */
+int nau8825_init_wakeup(struct snd_soc_codec *codec)
+{
+ struct nau8825 *nau8825 = snd_soc_codec_get_drvdata(codec);
+
+ device_init_wakeup(nau8825->dev, true);
+
+ return 0;
+}
+EXPORT_SYMBOL_GPL(nau8825_init_wakeup);
+
+/**
+ * nau8825_irq_wakeup - set interrupt can wakeup or not
+ *
+ * @codec: codec device component
+ * @on: switch interrupt wakeup on/off
+ *
+ * This function can enable or disable interrupt wakeup.
+ */
+int nau8825_irq_wakeup(struct snd_soc_codec *codec, int on)
+{
+ struct nau8825 *nau8825 = snd_soc_codec_get_drvdata(codec);
+
+ if (device_may_wakeup(nau8825->dev)) {
+ if (on)
+ enable_irq_wake(nau8825->irq);
+ else
+ disable_irq_wake(nau8825->irq);
+ }
+
+ return 0;
+}
+EXPORT_SYMBOL_GPL(nau8825_irq_wakeup);
static bool nau8825_is_jack_inserted(struct regmap *regmap)
{
@@ -676,7 +715,10 @@ static irqreturn_t nau8825_interrupt(int irq, void *data)
struct regmap *regmap = nau8825->regmap;
int active_irq, clear_irq = 0, event = 0, event_mask = 0;
- regmap_read(regmap, NAU8825_REG_IRQ_STATUS, &active_irq);
+ if (regmap_read(regmap, NAU8825_REG_IRQ_STATUS, &active_irq)) {
+ dev_err(nau8825->dev, "failed to clear interrupt\n");
+ return IRQ_NONE;
+ }
if ((active_irq & NAU8825_JACK_EJECTION_IRQ_MASK) ==
NAU8825_JACK_EJECTION_DETECTED) {
@@ -1092,6 +1134,36 @@ static int nau8825_set_sysclk(struct snd_soc_codec *codec, int clk_id,
return nau8825_configure_sysclk(nau8825, clk_id, freq);
}
+static int nau8825_resume_setup(struct nau8825 *nau8825)
+{
+ struct regmap *regmap = nau8825->regmap;
+
+ /* IRQ Output Enable */
+ regmap_update_bits(regmap, NAU8825_REG_INTERRUPT_MASK,
+ NAU8825_IRQ_OUTPUT_EN, NAU8825_IRQ_OUTPUT_EN);
+
+ /* Enable internal VCO needed for interruptions */
+ nau8825_configure_sysclk(nau8825, NAU8825_CLK_INTERNAL, 0);
+
+ /* Enable DDACR needed for interrupts */
+ regmap_update_bits(regmap, NAU8825_REG_ENA_CTRL,
+ NAU8825_ENABLE_DACR, NAU8825_ENABLE_DACR);
+
+ /* Chip needs one FSCLK cycle in order to generate interrupts,
+ * as we cannot guarantee one will be provided by the system. Turning
+ * master mode on then off enables us to generate that FSCLK cycle
+ * with a minimum of contention on the clock bus.
+ */
+ regmap_update_bits(regmap, NAU8825_REG_I2S_PCM_CTRL2,
+ NAU8825_I2S_MS_MASK, NAU8825_I2S_MS_MASTER);
+ regmap_update_bits(regmap, NAU8825_REG_I2S_PCM_CTRL2,
+ NAU8825_I2S_MS_MASK, NAU8825_I2S_MS_SLAVE);
+
+ nau8825_restart_jack_detection(regmap);
+
+ return 0;
+}
+
static int nau8825_set_bias_level(struct snd_soc_codec *codec,
enum snd_soc_bias_level level)
{
@@ -1121,6 +1193,8 @@ static int nau8825_set_bias_level(struct snd_soc_codec *codec,
"Failed to sync cache: %d\n", ret);
return ret;
}
+ if (nau8825->irq)
+ nau8825_resume_setup(nau8825);
}
break;
@@ -1330,24 +1404,22 @@ static int nau8825_i2c_remove(struct i2c_client *client)
#ifdef CONFIG_PM_SLEEP
static int nau8825_suspend(struct device *dev)
{
- struct i2c_client *client = to_i2c_client(dev);
struct nau8825 *nau8825 = dev_get_drvdata(dev);
+ struct snd_soc_codec *codec = snd_soc_dapm_to_codec(nau8825->dapm);
- disable_irq(client->irq);
+ disable_irq(nau8825->irq);
+ snd_soc_codec_force_bias_level(codec, SND_SOC_BIAS_OFF);
regcache_cache_only(nau8825->regmap, true);
- regcache_mark_dirty(nau8825->regmap);
return 0;
}
static int nau8825_resume(struct device *dev)
{
- struct i2c_client *client = to_i2c_client(dev);
struct nau8825 *nau8825 = dev_get_drvdata(dev);
regcache_cache_only(nau8825->regmap, false);
- regcache_sync(nau8825->regmap);
- enable_irq(client->irq);
+ enable_irq(nau8825->irq);
return 0;
}
diff --git a/sound/soc/codecs/nau8825.h b/sound/soc/codecs/nau8825.h
index 8237693..00e7661 100644
--- a/sound/soc/codecs/nau8825.h
+++ b/sound/soc/codecs/nau8825.h
@@ -347,6 +347,8 @@ struct nau8825 {
int nau8825_enable_jack_detect(struct snd_soc_codec *codec,
struct snd_soc_jack *jack);
+int nau8825_init_wakeup(struct snd_soc_codec *codec);
+int nau8825_irq_wakeup(struct snd_soc_codec *codec, int on);
#endif /* __NAU8825_H__ */
--
2.6.4
^ permalink raw reply related [flat|nested] 5+ messages in thread* Re: [PATCH] ASoC: nau8825: Modify power management and add interrupt wakeup
2016-01-08 7:11 [PATCH] ASoC: nau8825: Modify power management and add interrupt wakeup John Hsu
@ 2016-01-08 13:13 ` Mark Brown
[not found] ` <d255aac675d4418c87af834edc567021@NTHCML01B.nuvoton.com>
0 siblings, 1 reply; 5+ messages in thread
From: Mark Brown @ 2016-01-08 13:13 UTC (permalink / raw)
To: John Hsu
Cc: alsa-devel, anatol.pomozov, YHCHuang, lgirdwood, benzh, CTLIN0,
mhkuo, yong.zhi
[-- Attachment #1.1: Type: text/plain, Size: 1183 bytes --]
On Fri, Jan 08, 2016 at 03:11:22PM +0800, John Hsu wrote:
> 1. Enhance codec suspend and resume sequence
> 2. Add interrupt wakeup function
If this is two or more separate changes you should be sending two or
more separate patches. You also need a better changelog which describes
what the patch is supposed to do, in what way is suspend and resume
enhanced for example?
> +/**
> + * nau8825_init_wakeup - set wakeup capability for codec
> + *
> + * @codec: codec device component
> + *
> + * After this function done, codec can support system wakeup by button.
> + */
> +int nau8825_init_wakeup(struct snd_soc_codec *codec)
> +{
> + struct nau8825 *nau8825 = snd_soc_codec_get_drvdata(codec);
> +
> + device_init_wakeup(nau8825->dev, true);
> +
> + return 0;
> +}
> +EXPORT_SYMBOL_GPL(nau8825_init_wakeup);
You need a bit more explanation as to what's going on here. Why is this
not something the driver just does or if this should be done elsewhere
why do we need the wrapper function?
> +int nau8825_irq_wakeup(struct snd_soc_codec *codec, int on)
> +{
> + struct nau8825 *nau8825 = snd_soc_codec_get_drvdata(codec);
Same thing here, this looks like an unclear interface.
[-- Attachment #1.2: signature.asc --]
[-- Type: application/pgp-signature, Size: 473 bytes --]
[-- Attachment #2: Type: text/plain, Size: 0 bytes --]
^ permalink raw reply [flat|nested] 5+ messages in thread
end of thread, other threads:[~2016-02-25 17:36 UTC | newest]
Thread overview: 5+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2016-01-08 7:11 [PATCH] ASoC: nau8825: Modify power management and add interrupt wakeup John Hsu
2016-01-08 13:13 ` Mark Brown
[not found] ` <d255aac675d4418c87af834edc567021@NTHCML01B.nuvoton.com>
2016-02-24 23:09 ` John Hsu
2016-02-25 1:55 ` Mark Brown
2016-02-25 17:36 ` John Hsu
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.