static irqreturn_t ipq_mi2s_irq(int intrsrc, void *data) { int dma_ch; uint32_t ret = IRQ_NONE; uint32_t has_xrun, pending; struct snd_pcm_substream *substream = data; struct snd_pcm_runtime *runtime = substream->runtime; struct ipq_lpass_runtime_data_t *prtd = (struct ipq_lpass_runtime_data_t *)runtime->private_data; if (prtd) dma_ch = prtd->lpaif_info.dma_ch; else return IRQ_NONE; pending = (intrsrc & (UNDER_CH(dma_ch) | PER_CH(dma_ch) | ERR_CH(dma_ch))); has_xrun = (pending & UNDER_CH(dma_ch)); if (unlikely(has_xrun) && substream->runtime && snd_pcm_running(substream)) { pr_debug("%s %d: xrun warning\n", __func__, __LINE__); snd_pcm_stop(substream, SNDRV_PCM_STATE_XRUN); pending &= ~UNDER_CH(dma_ch); ret = IRQ_HANDLED; } if (pending & PER_CH(dma_ch)) { if (++prtd->pcm_stream_info.period_index >= runtime->periods) prtd->pcm_stream_info.period_index = 0; snd_pcm_period_elapsed(substream); pending &= ~PER_CH(dma_ch); ret = IRQ_HANDLED; } if (pending & UNDER_CH(dma_ch)) { snd_pcm_period_elapsed(substream); pr_debug("%s %d: xrun warning\n", __func__, __LINE__); ret = IRQ_HANDLED; } if (pending & ERR_CH(dma_ch)) { pr_debug("%s %d: Bus access warning\n", __func__, __LINE__); ret = IRQ_HANDLED; } return ret; }
static irqreturn_t lpa_if_irq(int intrsrc, void *data) { struct lpa_if *lpa_if = data; int dma_ch = 0; unsigned int pending; if (lpa_if) dma_ch = lpa_if->dma_ch; else { pr_err("invalid lpa_if\n"); return IRQ_NONE; } pending = (intrsrc & (UNDER_CH(dma_ch) | PER_CH(dma_ch) | ERR_CH(dma_ch))); if (pending & UNDER_CH(dma_ch)) pr_err("under run\n"); if (pending & ERR_CH(dma_ch)) pr_err("DMA %x Master Error\n", dma_ch); if (pending & PER_CH(dma_ch)) { lpa_if->audio_buf[lpa_if->dma_buf].used = 0; pr_debug("dma_buf %d used %d\n", lpa_if->dma_buf, lpa_if->audio_buf[lpa_if->dma_buf].used); lpa_if->dma_buf++; lpa_if->dma_buf = lpa_if->dma_buf % lpa_if->cfg.buffer_count; if (lpa_if->dma_buf == lpa_if->cpu_buf) pr_err("Err:both dma_buf and cpu_buf are on same index\n"); wake_up(&lpa_if->wait); } return IRQ_HANDLED; }