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; }
struct dmac_dma_xfer * dmac_prepare_xfer(struct dmac_channel_stat *chan, bus_dma_tag_t dmat, bus_dmamap_t dmamap, int dir, int scr, void *dar) { struct dmac_dma_xfer *xf; struct dmac_softc *dmac = chan->ch_softc; xf = dmac_alloc_xfer(chan, dmat, dmamap); xf->dx_ocr = dir & DMAC_OCR_DIR_MASK; xf->dx_scr = scr & (DMAC_SCR_MAC_MASK|DMAC_SCR_DAC_MASK); xf->dx_device = dar; dmac_load_xfer(dmac, xf); return xf; }