[Sound-open-firmware] [PATCH] ssp: Add IRQ handler to SSP port

Liam Girdwood liam.r.girdwood at linux.intel.com
Wed Sep 20 15:58:03 CEST 2017


Add an interrupt handler to slear any SSP IRQs. TODO: extend this to
report XRUNS and other errors.

Signed-off-by: Liam Girdwood <liam.r.girdwood at linux.intel.com>
---
 src/drivers/ssp.c      | 23 +++++++++++++++++++++++
 src/include/reef/ssp.h |  6 +++++-
 2 files changed, 28 insertions(+), 1 deletion(-)

diff --git a/src/drivers/ssp.c b/src/drivers/ssp.c
index 6d2c004..547c91c 100644
--- a/src/drivers/ssp.c
+++ b/src/drivers/ssp.c
@@ -370,6 +370,24 @@ static int ssp_trigger(struct dai *dai, int cmd, int direction)
 	return 0;
 }
 
+/* The IRQ handler allows the SSP port to drain the playback FIFO to make sure
+ * every sample has been played */
+static void ssp_irq_handler(void *data)
+{
+	struct dai *dai = data;
+	int i;
+
+	trace_value(ssp_read(dai, SSSR));
+
+	/* empty Rx FIFO */
+	for (i = 0; i < 16; i++)
+		ssp_read(dai, SSDR);
+
+	/* clear IRQ */
+	ssp_write(dai, SSSR, ssp_read(dai, SSSR));
+	platform_interrupt_clear(ssp_irq(dai), 1);
+}
+
 static int ssp_probe(struct dai *dai)
 {
 	struct ssp_pdata *ssp;
@@ -383,6 +401,11 @@ static int ssp_probe(struct dai *dai)
 	ssp->state[DAI_DIR_PLAYBACK] = COMP_STATE_READY;
 	ssp->state[DAI_DIR_CAPTURE] = COMP_STATE_READY;
 
+	/* register our IRQ handler */
+	interrupt_register(ssp_irq(dai), ssp_irq_handler, dai);
+	platform_interrupt_unmask(ssp_irq(dai), 1);
+	interrupt_enable(ssp_irq(dai));
+
 	return 0;
 }
 
diff --git a/src/include/reef/ssp.h b/src/include/reef/ssp.h
index 70113df..448a0dd 100644
--- a/src/include/reef/ssp.h
+++ b/src/include/reef/ssp.h
@@ -78,7 +78,7 @@ extern const struct dai_ops ssp_ops;
 #define SSCR0_EDSS	(1 << 20)
 #define SSCR0_NCS	(1 << 21)
 #define SSCR0_RIM	(1 << 22)
-#define SSCR0_TUM	(1 << 23)
+#define SSCR0_TIM	(1 << 23)
 #define SSCR0_FRDC(x)	((x - 1) << 24)
 #define SSCR0_ACS	(1 << 30)
 #define SSCR0_MOD	(1 << 31)
@@ -154,6 +154,10 @@ extern const struct dai_ops ssp_ops;
 #define trace_ssp_error(__e)	trace_error(TRACE_CLASS_SSP, __e)
 #define tracev_ssp(__e)	tracev_event(TRACE_CLASS_SSP, __e)
 
+
+#define ssp_irq(ssp) \
+	ssp->plat_data.irq
+
 /* SSP private data */
 struct ssp_pdata {
 	uint32_t sscr0;
-- 
2.11.0



More information about the Sound-open-firmware mailing list