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++; } }
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; }