示例#1
0
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;
}
示例#2
0
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;
}