Пример #1
0
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;
}