static int fms_intr(void *arg) { struct fms_softc *sc = arg; #if NMPU > 0 struct mpu_softc *sc_mpu = device_private(sc->sc_mpu_dev); #endif uint16_t istat; mutex_spin_enter(&sc->sc_intr_lock); istat = bus_space_read_2(sc->sc_iot, sc->sc_ioh, FM_INTSTATUS); if (istat & FM_INTSTATUS_PLAY) { if ((sc->sc_play_nextblk += sc->sc_play_blksize) >= sc->sc_play_end) sc->sc_play_nextblk = sc->sc_play_start; bus_space_write_4(sc->sc_iot, sc->sc_ioh, sc->sc_play_flip++ & 1 ? FM_PLAY_DMABUF2 : FM_PLAY_DMABUF1, sc->sc_play_nextblk); if (sc->sc_pintr) sc->sc_pintr(sc->sc_parg); else printf("unexpected play intr\n"); } if (istat & FM_INTSTATUS_REC) { if ((sc->sc_rec_nextblk += sc->sc_rec_blksize) >= sc->sc_rec_end) sc->sc_rec_nextblk = sc->sc_rec_start; bus_space_write_4(sc->sc_iot, sc->sc_ioh, sc->sc_rec_flip++ & 1 ? FM_REC_DMABUF2 : FM_REC_DMABUF1, sc->sc_rec_nextblk); if (sc->sc_rintr) sc->sc_rintr(sc->sc_rarg); else printf("unexpected rec intr\n"); } #if NMPU > 0 if (istat & FM_INTSTATUS_MPU) mpu_intr(sc_mpu); #endif bus_space_write_2(sc->sc_iot, sc->sc_ioh, FM_INTSTATUS, istat & (FM_INTSTATUS_PLAY | FM_INTSTATUS_REC)); mutex_spin_exit(&sc->sc_intr_lock); return 1; }
int yds_intr(void *p) { struct yds_softc *sc = p; u_int status; mtx_enter(&audio_lock); status = YREAD4(sc, YDS_STATUS); DPRINTFN(1, ("yds_intr: status=%08x\n", status)); if ((status & (YDS_STAT_INT|YDS_STAT_TINT)) == 0) { #if 0 if (sc->sc_mpu) return mpu_intr(sc->sc_mpu); #endif mtx_leave(&audio_lock); return 0; } if (status & YDS_STAT_TINT) { YWRITE4(sc, YDS_STATUS, YDS_STAT_TINT); printf ("yds_intr: timeout!\n"); } if (status & YDS_STAT_INT) { int nbank = (YREAD4(sc, YDS_CONTROL_SELECT) == 0); /* Clear interrupt flag */ YWRITE4(sc, YDS_STATUS, YDS_STAT_INT); /* Buffer for the next frame is always ready. */ YWRITE4(sc, YDS_MODE, YREAD4(sc, YDS_MODE) | YDS_MODE_ACTV2); if (sc->sc_play.intr) { u_int dma, cpu, blk, len; /* Sync play slot control data */ bus_dmamap_sync(sc->sc_dmatag, sc->sc_ctrldata.map, sc->pbankoff, sizeof(struct play_slot_ctrl_bank)* (*sc->ptbl)* N_PLAY_SLOT_CTRL_BANK, BUS_DMASYNC_POSTWRITE| BUS_DMASYNC_POSTREAD); dma = sc->pbankp[nbank]->pgstart * sc->sc_play.factor; cpu = sc->sc_play.offset; blk = sc->sc_play.blksize; len = sc->sc_play.length; if (((dma > cpu) && (dma - cpu > blk * 2)) || ((cpu > dma) && (dma + len - cpu > blk * 2))) { /* We can fill the next block */ /* Sync ring buffer for previous write */ bus_dmamap_sync(sc->sc_dmatag, sc->sc_play.dma->map, cpu, blk, BUS_DMASYNC_POSTWRITE); sc->sc_play.intr(sc->sc_play.intr_arg); sc->sc_play.offset += blk; if (sc->sc_play.offset >= len) { sc->sc_play.offset -= len; #ifdef DIAGNOSTIC if (sc->sc_play.offset != 0) printf ("Audio ringbuffer botch\n"); #endif } /* Sync ring buffer for next write */ bus_dmamap_sync(sc->sc_dmatag, sc->sc_play.dma->map, cpu, blk, BUS_DMASYNC_PREWRITE); } } if (sc->sc_rec.intr) { u_int dma, cpu, blk, len; /* Sync rec slot control data */ bus_dmamap_sync(sc->sc_dmatag, sc->sc_ctrldata.map, sc->rbankoff, sizeof(struct rec_slot_ctrl_bank)* N_REC_SLOT_CTRL* N_REC_SLOT_CTRL_BANK, BUS_DMASYNC_POSTWRITE| BUS_DMASYNC_POSTREAD); dma = sc->rbank[YDS_INPUT_SLOT*2 + nbank].pgstartadr; cpu = sc->sc_rec.offset; blk = sc->sc_rec.blksize; len = sc->sc_rec.length; if (((dma > cpu) && (dma - cpu > blk * 2)) || ((cpu > dma) && (dma + len - cpu > blk * 2))) { /* We can drain the current block */ /* Sync ring buffer first */ bus_dmamap_sync(sc->sc_dmatag, sc->sc_rec.dma->map, cpu, blk, BUS_DMASYNC_POSTREAD); sc->sc_rec.intr(sc->sc_rec.intr_arg); sc->sc_rec.offset += blk; if (sc->sc_rec.offset >= len) { sc->sc_rec.offset -= len; #ifdef DIAGNOSTIC if (sc->sc_rec.offset != 0) printf ("Audio ringbuffer botch\n"); #endif } /* Sync ring buffer for next read */ bus_dmamap_sync(sc->sc_dmatag, sc->sc_rec.dma->map, cpu, blk, BUS_DMASYNC_PREREAD); } } } mtx_leave(&audio_lock); return 1; }