static void stop_corb_rirb(struct lola *chip) { /* */ lola_writeb(chip, BAR0, RIRBCTL, 0); lola_writeb(chip, BAR0, CORBCTL, 0); }
static int setup_corb_rirb(struct lola *chip) { int err; unsigned char tmp; unsigned long end_time; err = snd_dma_alloc_pages(SNDRV_DMA_TYPE_DEV, snd_dma_pci_data(chip->pci), PAGE_SIZE, &chip->rb); if (err < 0) return err; chip->corb.addr = chip->rb.addr; chip->corb.buf = (u32 *)chip->rb.area; chip->rirb.addr = chip->rb.addr + 2048; chip->rirb.buf = (u32 *)(chip->rb.area + 2048); /* */ lola_writeb(chip, BAR0, RIRBCTL, 0); lola_writeb(chip, BAR0, CORBCTL, 0); end_time = jiffies + msecs_to_jiffies(200); do { if (!lola_readb(chip, BAR0, RIRBCTL) && !lola_readb(chip, BAR0, CORBCTL)) break; msleep(1); } while (time_before(jiffies, end_time)); /* */ lola_writel(chip, BAR0, CORBLBASE, (u32)chip->corb.addr); lola_writel(chip, BAR0, CORBUBASE, upper_32_bits(chip->corb.addr)); /* */ lola_writeb(chip, BAR0, CORBSIZE, 0x02); /* */ lola_writew(chip, BAR0, CORBWP, 0); /* */ lola_writew(chip, BAR0, CORBRP, LOLA_RBRWP_CLR); /* */ lola_writeb(chip, BAR0, CORBCTL, LOLA_RBCTL_DMA_EN); /* */ tmp = lola_readb(chip, BAR0, CORBSTS) & LOLA_CORB_INT_MASK; if (tmp) lola_writeb(chip, BAR0, CORBSTS, tmp); chip->corb.wp = 0; /* */ lola_writel(chip, BAR0, RIRBLBASE, (u32)chip->rirb.addr); lola_writel(chip, BAR0, RIRBUBASE, upper_32_bits(chip->rirb.addr)); /* */ lola_writeb(chip, BAR0, RIRBSIZE, 0x02); /* */ lola_writew(chip, BAR0, RIRBWP, LOLA_RBRWP_CLR); /* */ lola_writew(chip, BAR0, RINTCNT, 1); /* */ lola_writeb(chip, BAR0, RIRBCTL, LOLA_RBCTL_DMA_EN | LOLA_RBCTL_IRQ_EN); /* */ tmp = lola_readb(chip, BAR0, RIRBSTS) & LOLA_RIRB_INT_MASK; if (tmp) lola_writeb(chip, BAR0, RIRBSTS, tmp); chip->rirb.rp = chip->rirb.cmds = 0; return 0; }
static void stop_corb_rirb(struct lola *chip) { /* disable ringbuffer DMAs */ lola_writeb(chip, BAR0, RIRBCTL, 0); lola_writeb(chip, BAR0, CORBCTL, 0); }
static irqreturn_t lola_interrupt(int irq, void *dev_id) { struct lola *chip = dev_id; unsigned int notify_ins, notify_outs, error_ins, error_outs; int handled = 0; int i; notify_ins = notify_outs = error_ins = error_outs = 0; spin_lock(&chip->reg_lock); for (;;) { unsigned int status, in_sts, out_sts; unsigned int reg; status = lola_readl(chip, BAR1, DINTSTS); if (!status || status == -1) break; in_sts = lola_readl(chip, BAR1, DIINTSTS); out_sts = lola_readl(chip, BAR1, DOINTSTS); /* */ for (i = 0; in_sts && i < chip->pcm[CAPT].num_streams; i++) { if (!(in_sts & (1 << i))) continue; in_sts &= ~(1 << i); reg = lola_dsd_read(chip, i, STS); if (reg & LOLA_DSD_STS_DESE) /* */ error_ins |= (1 << i); if (reg & LOLA_DSD_STS_BCIS) /* */ notify_ins |= (1 << i); /* */ lola_dsd_write(chip, i, STS, reg); } /* */ for (i = 0; out_sts && i < chip->pcm[PLAY].num_streams; i++) { if (!(out_sts & (1 << i))) continue; out_sts &= ~(1 << i); reg = lola_dsd_read(chip, i + MAX_STREAM_IN_COUNT, STS); if (reg & LOLA_DSD_STS_DESE) /* */ error_outs |= (1 << i); if (reg & LOLA_DSD_STS_BCIS) /* */ notify_outs |= (1 << i); lola_dsd_write(chip, i + MAX_STREAM_IN_COUNT, STS, reg); } if (status & LOLA_DINT_CTRL) { unsigned char rbsts; /* */ rbsts = lola_readb(chip, BAR0, RIRBSTS); rbsts &= LOLA_RIRB_INT_MASK; if (rbsts) lola_writeb(chip, BAR0, RIRBSTS, rbsts); rbsts = lola_readb(chip, BAR0, CORBSTS); rbsts &= LOLA_CORB_INT_MASK; if (rbsts) lola_writeb(chip, BAR0, CORBSTS, rbsts); lola_update_rirb(chip); } if (status & (LOLA_DINT_FIFOERR | LOLA_DINT_MUERR)) { /* */ lola_writel(chip, BAR1, DINTSTS, (status & (LOLA_DINT_FIFOERR | LOLA_DINT_MUERR))); } handled = 1; } spin_unlock(&chip->reg_lock); lola_pcm_update(chip, &chip->pcm[CAPT], notify_ins); lola_pcm_update(chip, &chip->pcm[PLAY], notify_outs); return IRQ_RETVAL(handled); }
static int setup_corb_rirb(struct lola *chip) { int err; unsigned char tmp; unsigned long end_time; err = snd_dma_alloc_pages(SNDRV_DMA_TYPE_DEV, snd_dma_pci_data(chip->pci), PAGE_SIZE, &chip->rb); if (err < 0) return err; chip->corb.addr = chip->rb.addr; chip->corb.buf = (u32 *)chip->rb.area; chip->rirb.addr = chip->rb.addr + 2048; chip->rirb.buf = (u32 *)(chip->rb.area + 2048); /* disable ringbuffer DMAs */ lola_writeb(chip, BAR0, RIRBCTL, 0); lola_writeb(chip, BAR0, CORBCTL, 0); end_time = jiffies + msecs_to_jiffies(200); do { if (!lola_readb(chip, BAR0, RIRBCTL) && !lola_readb(chip, BAR0, CORBCTL)) break; msleep(1); } while (time_before(jiffies, end_time)); /* CORB set up */ lola_writel(chip, BAR0, CORBLBASE, (u32)chip->corb.addr); lola_writel(chip, BAR0, CORBUBASE, upper_32_bits(chip->corb.addr)); /* set the corb size to 256 entries */ lola_writeb(chip, BAR0, CORBSIZE, 0x02); /* set the corb write pointer to 0 */ lola_writew(chip, BAR0, CORBWP, 0); /* reset the corb hw read pointer */ lola_writew(chip, BAR0, CORBRP, LOLA_RBRWP_CLR); /* enable corb dma */ lola_writeb(chip, BAR0, CORBCTL, LOLA_RBCTL_DMA_EN); /* clear flags if set */ tmp = lola_readb(chip, BAR0, CORBSTS) & LOLA_CORB_INT_MASK; if (tmp) lola_writeb(chip, BAR0, CORBSTS, tmp); chip->corb.wp = 0; /* RIRB set up */ lola_writel(chip, BAR0, RIRBLBASE, (u32)chip->rirb.addr); lola_writel(chip, BAR0, RIRBUBASE, upper_32_bits(chip->rirb.addr)); /* set the rirb size to 256 entries */ lola_writeb(chip, BAR0, RIRBSIZE, 0x02); /* reset the rirb hw write pointer */ lola_writew(chip, BAR0, RIRBWP, LOLA_RBRWP_CLR); /* set N=1, get RIRB response interrupt for new entry */ lola_writew(chip, BAR0, RINTCNT, 1); /* enable rirb dma and response irq */ lola_writeb(chip, BAR0, RIRBCTL, LOLA_RBCTL_DMA_EN | LOLA_RBCTL_IRQ_EN); /* clear flags if set */ tmp = lola_readb(chip, BAR0, RIRBSTS) & LOLA_RIRB_INT_MASK; if (tmp) lola_writeb(chip, BAR0, RIRBSTS, tmp); chip->rirb.rp = chip->rirb.cmds = 0; return 0; }