static void ad1889_interrupt(int irq, void *dev_id, struct pt_regs *regs)
{
	u32 stat;
	ad1889_dev_t *dev = (ad1889_dev_t *)dev_id;

	stat = AD1889_READL(dev, AD_DMADISR);

	/* clear ISR */
	AD1889_WRITEL(dev, AD_DMADISR, stat);

	if (stat & 0x8) {		/* WAVI */
		DBG("WAV interrupt\n");
		dev->stats.wav_intrs++;
		if (dev->state[AD_WAV_STATE].dmabuf.ready) {
			ad1889_stop_wav(&dev->state[AD_WAV_STATE]);	/* clean up */
			ad1889_start_wav(&dev->state[AD_WAV_STATE]);	/* start new */
		}

	}

	if (stat & 0x2 && dev->state[AD_ADC_STATE].dmabuf.ready) { /* ADCI */
		DBG("ADC interrupt\n");
		dev->stats.adc_intrs++;
	}
}
Example #2
0
static irqreturn_t ad1889_interrupt(int irq, void *dev_id)
{
	u32 stat;
	ad1889_dev_t *dev = (ad1889_dev_t *)dev_id;

	stat = AD1889_READL(dev, AD_DMA_DISR);

	/* clear ISR */
	AD1889_WRITEL(dev, AD_DMA_DISR, stat);

	if (stat & 0x8) {		/* WAVI */
		DBG("WAV interrupt\n");
		dev->stats.wav_intrs++;
		if (dev->state[AD_WAV_STATE].dmabuf.ready) {
			ad1889_stop_wav(&dev->state[AD_WAV_STATE]);	/* clean up */
			ad1889_start_wav(&dev->state[AD_WAV_STATE]);	/* start new */
		}
	}

	if ((stat & 0x2) && dev->state[AD_ADC_STATE].dmabuf.ready) { /* ADCI */
		DBG("ADC interrupt\n");
		dev->stats.adc_intrs++;
	}
	if(stat)
		return IRQ_HANDLED;
	return IRQ_NONE;
}
static void ad1889_start_wav(ad1889_state_t *state)
{
	unsigned long flags;
	struct dmabuf *dmabuf = &state->dmabuf;
	int cnt;
	u16 tmp;

	spin_lock_irqsave(&state->card->lock, flags);

	if (dmabuf->dma_len)	/* DMA already in flight */
		goto skip_dma;

	/* setup dma */
	cnt = dmabuf->wr_ptr - dmabuf->rd_ptr;
	if (cnt == 0)		/* done - don't need to do anything */
		goto skip_dma;

	/* If the wr_ptr has wrapped, only map to the end */
	if (cnt < 0)
		cnt = DMA_SIZE - dmabuf->rd_ptr;

	dmabuf->dma_handle = pci_map_single(ad1889_dev->pci,
					dmabuf->rawbuf + dmabuf->rd_ptr,
					cnt, PCI_DMA_TODEVICE);
	dmabuf->dma_len = cnt;
	dmabuf->ready = 1;

	DBG("Starting playback at 0x%p for %ld bytes\n", dmabuf->rawbuf +
	    dmabuf->rd_ptr, dmabuf->dma_len);

        /* load up the current register set */
	AD1889_WRITEL(ad1889_dev, AD_DMAWAVCC, cnt);
	AD1889_WRITEL(ad1889_dev, AD_DMAWAVICC, cnt);
	AD1889_WRITEL(ad1889_dev, AD_DMAWAVCA, dmabuf->dma_handle);

	/* TODO: for now we load the base registers with the same thing */
	AD1889_WRITEL(ad1889_dev, AD_DMAWAVBC, cnt);
	AD1889_WRITEL(ad1889_dev, AD_DMAWAVIBC, cnt);
	AD1889_WRITEL(ad1889_dev, AD_DMAWAVBA, dmabuf->dma_handle);

	/* and we're off to the races... */
	AD1889_WRITEL(ad1889_dev, AD_DMACHSS, 0x8);
	tmp = AD1889_READW(ad1889_dev, AD_DSWSMC);
	tmp |= 0x0400; /* set WAEN */
	AD1889_WRITEW(ad1889_dev, AD_DSWSMC, tmp);
	(void) AD1889_READW(ad1889_dev, AD_DSWSMC); /* flush posted PCI write */

	dmabuf->enable |= DAC_RUNNING;

skip_dma:
	spin_unlock_irqrestore(&state->card->lock, flags);
}
static void ad1889_initcfg(ad1889_dev_t *dev)
{
	u16 tmp16;
	u32 tmp32;

	/* make sure the interrupt bits are setup the way we want */
	tmp32 = AD1889_READL(dev, AD_DMAWAVCTRL);
	tmp32 &= ~0xff; /* flat dma, no sg, mask out the intr bits */
	tmp32 |= 0x6;  /* intr on count, loop */
	AD1889_WRITEL(dev, AD_DMAWAVCTRL, tmp32);

	/* unmute... */
	tmp16 = AD1889_READW(dev, AD_DSWADA);
	tmp16 &= ~0x8080;
	AD1889_WRITEW(dev, AD_DSWADA, tmp16);
}