Esempio n. 1
0
/*
 * vs interrupt handler
 */
static int
vs_dmaintr(void *hdl)
{
	struct vs_softc *sc;

	DPRINTF(2, ("vs_dmaintr\n"));
	sc = hdl;

	mutex_spin_enter(&sc->sc_intr_lock);

	if (sc->sc_pintr) {
		/* start next transfer */
		sc->sc_current.dmap += sc->sc_current.blksize;
		if (sc->sc_current.dmap + sc->sc_current.blksize
		    > sc->sc_current.bufsize)
			sc->sc_current.dmap -= sc->sc_current.bufsize;
		dmac_start_xfer_offset(sc->sc_dma_ch->ch_softc,
					sc->sc_current.xfer,
					sc->sc_current.dmap,
					sc->sc_current.blksize);
		sc->sc_pintr(sc->sc_parg);
	} else if (sc->sc_rintr) {
		/* start next transfer */
		sc->sc_current.dmap += sc->sc_current.blksize;
		if (sc->sc_current.dmap + sc->sc_current.blksize
		    > sc->sc_current.bufsize)
			sc->sc_current.dmap -= sc->sc_current.bufsize;
		dmac_start_xfer_offset(sc->sc_dma_ch->ch_softc,
					sc->sc_current.xfer,
					sc->sc_current.dmap,
					sc->sc_current.blksize);
		sc->sc_rintr(sc->sc_rarg);
	} else {
		printf("vs_dmaintr: spurious interrupt\n");
	}

	mutex_spin_exit(&sc->sc_intr_lock);

	return 1;
}
Esempio n. 2
0
static int
vs_trigger_output(void *hdl, void *start, void *end, int bsize,
		  void (*intr)(void *), void *arg,
		  const audio_params_t *p)
{
	struct vs_softc *sc;
	struct vs_dma *vd;
	struct dmac_dma_xfer *xf;
	struct dmac_channel_stat *chan;

	DPRINTF(2, ("vs_trigger_output: start=%p, bsize=%d, intr=%p, arg=%p\n",
		 start, bsize, intr, arg));
	sc = hdl;
	chan = sc->sc_dma_ch;
	sc->sc_pintr = intr;
	sc->sc_parg  = arg;
	sc->sc_current.blksize = bsize;
	sc->sc_current.bufsize = (char *)end - (char *)start;
	sc->sc_current.dmap = 0;

	/* Find DMA buffer. */
	for (vd = sc->sc_dmas; vd != NULL && KVADDR(vd) != start;
	     vd = vd->vd_next)
		continue;
	if (vd == NULL) {
		printf("%s: trigger_output: bad addr %p\n",
		    device_xname(sc->sc_dev), start);
		return EINVAL;
	}

	vs_set_sr(sc, sc->sc_current.prate);
	vs_set_po(sc, VS_PANOUT_LR);

	xf = dmac_alloc_xfer(chan, sc->sc_dmat, vd->vd_map);
	sc->sc_current.xfer = xf;
	chan->ch_dcr = (DMAC_DCR_XRM_CSWOH | DMAC_DCR_OTYP_EASYNC |
			DMAC_DCR_OPS_8BIT);
	chan->ch_ocr = DMAC_OCR_REQG_EXTERNAL;
	xf->dx_ocr = DMAC_OCR_DIR_MTD;
	xf->dx_scr = DMAC_SCR_MAC_COUNT_UP | DMAC_SCR_DAC_NO_COUNT;
	xf->dx_device = sc->sc_addr + MSM6258_DATA*2 + 1;

	dmac_load_xfer(chan->ch_softc, xf);
	dmac_start_xfer_offset(chan->ch_softc, xf, 0, sc->sc_current.blksize);
	bus_space_write_1(sc->sc_iot, sc->sc_ioh, MSM6258_STAT, 2);

	return 0;
}
Esempio n. 3
0
/*
 * Do the actual transfer.
 */
int
dmac_start_xfer(struct dmac_softc *dmac, struct dmac_dma_xfer *xf)
{
	return dmac_start_xfer_offset(dmac, xf, 0, 0);
}