diff --git a/src/drivers/ssp.c b/src/drivers/ssp.c index 6d2c00496..547c91cf9 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 70113df36..448a0ddea 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;