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++;
	}
}
Esempio n. 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 inline unsigned long ad1889_get_dma_addr(ad1889_state_t *state)
{
	struct dmabuf *dmabuf = &state->dmabuf;
	u32 offset;

	if (!(dmabuf->enable & (DAC_RUNNING | ADC_RUNNING))) {
		printk(KERN_ERR DEVNAME ": get_dma_addr called without dma enabled\n");
		return 0;
	}
	
	if (dmabuf->enable & DAC_RUNNING)
		offset = le32_to_cpu(AD1889_READL(state->card, AD_DMAWAVBA));
	else
		offset = le32_to_cpu(AD1889_READL(state->card, AD_DMAADCBA));

	return (unsigned long)bus_to_virt((unsigned long)offset) - (unsigned long)dmabuf->rawbuf;
}
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);
}
int ad1889_read_proc (char *page, char **start, off_t off,
		      int count, int *eof, void *data)
{
	char *out = page;
	int len, i;
	ad1889_dev_t *dev = data;
	ad1889_reg_t regs[] = {
		{ "WSMC", AD_DSWSMC, 16 },
		{ "RAMC", AD_DSRAMC, 16 },
		{ "WADA", AD_DSWADA, 16 },
		{ "SYDA", AD_DSSYDA, 16 },
		{ "WAS", AD_DSWAS, 16 },
		{ "RES", AD_DSRES, 16 },
		{ "CCS", AD_DSCCS, 16 },
		{ "ADCBA", AD_DMAADCBA, 32 },
		{ "ADCCA", AD_DMAADCCA, 32 },
		{ "ADCBC", AD_DMAADCBC, 32 },
		{ "ADCCC", AD_DMAADCCC, 32 },
		{ "ADCIBC", AD_DMAADCIBC, 32 },
		{ "ADCICC", AD_DMAADCICC, 32 },
		{ "ADCCTRL", AD_DMAADCCTRL, 16 },
		{ "WAVBA", AD_DMAWAVBA, 32 },
		{ "WAVCA", AD_DMAWAVCA, 32 },
		{ "WAVBC", AD_DMAWAVBC, 32 },
		{ "WAVCC", AD_DMAWAVCC, 32 },
		{ "WAVIBC", AD_DMAWAVIBC, 32 },
		{ "WAVICC", AD_DMAWAVICC, 32 },
		{ "WAVCTRL", AD_DMAWAVCTRL, 16 },
		{ "DISR", AD_DMADISR, 32 },
		{ "CHSS", AD_DMACHSS, 32 },
		{ "IPC", AD_GPIOIPC, 16 },
		{ "OP", AD_GPIOOP, 16 },
		{ "IP", AD_GPIOIP, 16 },
		{ "ACIC", AD_ACIC, 16 },
		{ "AC97_RESET", 0x100 + AC97_RESET, 16 },
		{ "AC97_MASTER_VOL_STEREO", 0x100 + AC97_MASTER_VOL_STEREO, 16 },
		{ "AC97_HEADPHONE_VOL", 0x100 + AC97_HEADPHONE_VOL, 16 },
		{ "AC97_MASTER_VOL_MONO", 0x100 + AC97_MASTER_VOL_MONO, 16 },
		{ "AC97_MASTER_TONE", 0x100 + AC97_MASTER_TONE, 16 },
		{ "AC97_PCBEEP_VOL", 0x100 + AC97_PCBEEP_VOL, 16 },
		{ "AC97_PHONE_VOL", 0x100 + AC97_PHONE_VOL, 16 },
		{ "AC97_MIC_VOL", 0x100 + AC97_MIC_VOL, 16 },
		{ "AC97_LINEIN_VOL", 0x100 + AC97_LINEIN_VOL, 16 },
		{ "AC97_CD_VOL", 0x100 + AC97_CD_VOL, 16 },
		{ "AC97_VIDEO_VOL", 0x100 + AC97_VIDEO_VOL, 16 },
		{ "AC97_AUX_VOL", 0x100 + AC97_AUX_VOL, 16 },
		{ "AC97_PCMOUT_VOL", 0x100 + AC97_PCMOUT_VOL, 16 },
		{ "AC97_RECORD_SELECT", 0x100 + AC97_RECORD_SELECT, 16 },
		{ "AC97_RECORD_GAIN", 0x100 + AC97_RECORD_GAIN, 16 },
		{ "AC97_RECORD_GAIN_MIC", 0x100 + AC97_RECORD_GAIN_MIC, 16 },
		{ "AC97_GENERAL_PURPOSE", 0x100 + AC97_GENERAL_PURPOSE, 16 },
		{ "AC97_3D_CONTROL", 0x100 + AC97_3D_CONTROL, 16 },
		{ "AC97_MODEM_RATE", 0x100 + AC97_MODEM_RATE, 16 },
		{ "AC97_POWER_CONTROL", 0x100 + AC97_POWER_CONTROL, 16 },
		{ 0 }
	};

	if (dev == NULL)
		return -ENODEV;

	for (i = 0; regs[i].name != 0; i++)
		out += sprintf(out, "%s: 0x%0*x\n", regs[i].name, 
			regs[i].width >> 2, 
			(regs[i].width == 16 
			 	? AD1889_READW(dev, regs[i].offset)
				: AD1889_READL(dev, regs[i].offset)));

	for (i = 0; i < AD_MAX_STATES; i++) {
		out += sprintf(out, "DMA status for %s:\n", 
			(i == AD_WAV_STATE ? "WAV" : "ADC")); 
		out += sprintf(out, "\t\t0x%p (IOVA: 0x%u)\n", 
			dev->state[i].dmabuf.rawbuf,
			dev->state[i].dmabuf.dma_handle);

		out += sprintf(out, "\tread ptr: offset %u\n", 
			(unsigned int)dev->state[i].dmabuf.rd_ptr);
		out += sprintf(out, "\twrite ptr: offset %u\n", 
			(unsigned int)dev->state[i].dmabuf.wr_ptr);
		out += sprintf(out, "\tdma len: offset %u\n", 
			(unsigned int)dev->state[i].dmabuf.dma_len);
	}

	len = out - page - off;
	if (len < count) {
		*eof = 1;
		if (len <= 0) return 0;
	} else {
		len = count;
	}
	*start = page + off;
	return len;
}