All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH 1/2] ASoC: Implement DC servo completion IRQ handling for wm_hubs devices
@ 2011-07-12  7:59 Mark Brown
  2011-07-12  7:59 ` [PATCH 2/2] ASoC: Hook up DC servo completion IRQ for WM8994 and WM8958 Mark Brown
  0 siblings, 1 reply; 2+ messages in thread
From: Mark Brown @ 2011-07-12  7:59 UTC (permalink / raw)
  To: Liam Girdwood; +Cc: alsa-devel, patches, Mark Brown

The individual devices should set the flag dcs_done_irq in the hubs
shared data structure to indicate that they will flag the interrupt
by calling wm_hubs_dcs_done().

Signed-off-by: Mark Brown <broonie@opensource.wolfsonmicro.com>
---
 sound/soc/codecs/wm_hubs.c |   34 +++++++++++++++++++++++++++++-----
 sound/soc/codecs/wm_hubs.h |    8 ++++++++
 2 files changed, 37 insertions(+), 5 deletions(-)

diff --git a/sound/soc/codecs/wm_hubs.c b/sound/soc/codecs/wm_hubs.c
index 7e60e22..5c2d565 100644
--- a/sound/soc/codecs/wm_hubs.c
+++ b/sound/soc/codecs/wm_hubs.c
@@ -63,9 +63,11 @@ static const struct soc_enum speaker_mode =
 
 static void wait_for_dc_servo(struct snd_soc_codec *codec, unsigned int op)
 {
+	struct wm_hubs_data *hubs = snd_soc_codec_get_drvdata(codec);
 	unsigned int reg;
 	int count = 0;
 	unsigned int val;
+	unsigned long timeout;
 
 	val = op | WM8993_DCS_ENA_CHAN_0 | WM8993_DCS_ENA_CHAN_1;
 
@@ -74,18 +76,37 @@ static void wait_for_dc_servo(struct snd_soc_codec *codec, unsigned int op)
 
 	dev_dbg(codec->dev, "Waiting for DC servo...\n");
 
-	do {
-		count++;
-		msleep(1);
+	if (hubs->dcs_done_irq) {
+		timeout = wait_for_completion_timeout(&hubs->dcs_done,
+						      msecs_to_jiffies(500));
+		if (timeout == 0)
+			dev_warn(codec->dev, "No DC servo interrupt\n");
+
 		reg = snd_soc_read(codec, WM8993_DC_SERVO_0);
-		dev_dbg(codec->dev, "DC servo: %x\n", reg);
-	} while (reg & op && count < 400);
+	} else {
+		do {
+			count++;
+			msleep(1);
+			reg = snd_soc_read(codec, WM8993_DC_SERVO_0);
+			dev_dbg(codec->dev, "DC servo: %x\n", reg);
+		} while (reg & op && count < 400);
+	}
 
 	if (reg & op)
 		dev_err(codec->dev, "Timed out waiting for DC Servo %x\n",
 			op);
 }
 
+irqreturn_t wm_hubs_dcs_done(int irq, void *data)
+{
+	struct wm_hubs_data *hubs = data;
+
+	complete(&hubs->dcs_done);
+
+	return IRQ_HANDLED;
+}
+EXPORT_SYMBOL_GPL(wm_hubs_dcs_done);
+
 /*
  * Startup calibration of the DC servo
  */
@@ -863,8 +884,11 @@ EXPORT_SYMBOL_GPL(wm_hubs_add_analogue_controls);
 int wm_hubs_add_analogue_routes(struct snd_soc_codec *codec,
 				int lineout1_diff, int lineout2_diff)
 {
+	struct wm_hubs_data *hubs = snd_soc_codec_get_drvdata(codec);
 	struct snd_soc_dapm_context *dapm = &codec->dapm;
 
+	init_completion(&hubs->dcs_done);
+
 	snd_soc_dapm_add_routes(dapm, analogue_routes,
 				ARRAY_SIZE(analogue_routes));
 
diff --git a/sound/soc/codecs/wm_hubs.h b/sound/soc/codecs/wm_hubs.h
index 0d290d2..676b125 100644
--- a/sound/soc/codecs/wm_hubs.h
+++ b/sound/soc/codecs/wm_hubs.h
@@ -14,6 +14,9 @@
 #ifndef _WM_HUBS_H
 #define _WM_HUBS_H
 
+#include <linux/completion.h>
+#include <linux/interrupt.h>
+
 struct snd_soc_codec;
 
 extern const unsigned int wm_hubs_spkmix_tlv[];
@@ -28,6 +31,9 @@ struct wm_hubs_data {
 
 	bool class_w;
 	u16 class_w_dcs;
+
+	bool dcs_done_irq;
+	struct completion dcs_done;
 };
 
 extern int wm_hubs_add_analogue_controls(struct snd_soc_codec *);
@@ -38,4 +44,6 @@ extern int wm_hubs_handle_analogue_pdata(struct snd_soc_codec *,
 					 int jd_scthr, int jd_thr,
 					 int micbias1_lvl, int micbias2_lvl);
 
+extern irqreturn_t wm_hubs_dcs_done(int irq, void *data);
+
 #endif
-- 
1.7.5.4

^ permalink raw reply related	[flat|nested] 2+ messages in thread

* [PATCH 2/2] ASoC: Hook up DC servo completion IRQ for WM8994 and WM8958
  2011-07-12  7:59 [PATCH 1/2] ASoC: Implement DC servo completion IRQ handling for wm_hubs devices Mark Brown
@ 2011-07-12  7:59 ` Mark Brown
  0 siblings, 0 replies; 2+ messages in thread
From: Mark Brown @ 2011-07-12  7:59 UTC (permalink / raw)
  To: Liam Girdwood; +Cc: alsa-devel, patches, Mark Brown

Signed-off-by: Mark Brown <broonie@opensource.wolfsonmicro.com>
---
 sound/soc/codecs/wm8994.c |   11 +++++++++++
 1 files changed, 11 insertions(+), 0 deletions(-)

diff --git a/sound/soc/codecs/wm8994.c b/sound/soc/codecs/wm8994.c
index e90ae9d..c49e698 100644
--- a/sound/soc/codecs/wm8994.c
+++ b/sound/soc/codecs/wm8994.c
@@ -2972,6 +2972,12 @@ static int wm8994_codec_probe(struct snd_soc_codec *codec)
 		break;
 	}
 
+	ret = wm8994_request_irq(codec->control_data, WM8994_IRQ_DCS_DONE,
+				 wm_hubs_dcs_done, "DC servo done",
+				 &wm8994->hubs);
+	if (ret == 0)
+		wm8994->hubs.dcs_done_irq = true;
+
 	switch (control->type) {
 	case WM8994:
 		if (wm8994->micdet_irq) {
@@ -3243,6 +3249,8 @@ err_irq:
 	wm8994_free_irq(codec->control_data, WM8994_IRQ_MIC1_SHRT, wm8994);
 	if (wm8994->micdet_irq)
 		free_irq(wm8994->micdet_irq, wm8994);
+	wm8994_free_irq(codec->control_data, WM8994_IRQ_DCS_DONE,
+			&wm8994->hubs);
 err:
 	kfree(wm8994);
 	return ret;
@@ -3257,6 +3265,9 @@ static int  wm8994_codec_remove(struct snd_soc_codec *codec)
 
 	pm_runtime_disable(codec->dev);
 
+	wm8994_free_irq(codec->control_data, WM8994_IRQ_DCS_DONE,
+			&wm8994->hubs);
+
 	switch (control->type) {
 	case WM8994:
 		if (wm8994->micdet_irq)
-- 
1.7.5.4

^ permalink raw reply related	[flat|nested] 2+ messages in thread

end of thread, other threads:[~2011-07-12  7:59 UTC | newest]

Thread overview: 2+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2011-07-12  7:59 [PATCH 1/2] ASoC: Implement DC servo completion IRQ handling for wm_hubs devices Mark Brown
2011-07-12  7:59 ` [PATCH 2/2] ASoC: Hook up DC servo completion IRQ for WM8994 and WM8958 Mark Brown

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.