int auvia_intr(void *arg) { struct auvia_softc *sc = arg; struct auvia_softc_chan *ch; u_int8_t r; int i = 0; ch = &sc->sc_record; r = CH_READ1(sc, ch, AUVIA_RP_STAT); if (r & AUVIA_RPSTAT_INTR) { if (sc->sc_record.sc_intr) sc->sc_record.sc_intr(sc->sc_record.sc_arg); /* clear interrupts */ CH_WRITE1(sc, ch, AUVIA_RP_STAT, AUVIA_RPSTAT_INTR); i++; } ch = &sc->sc_play; r = CH_READ1(sc, ch, AUVIA_RP_STAT); if (r & AUVIA_RPSTAT_INTR) { if (sc->sc_play.sc_intr) sc->sc_play.sc_intr(sc->sc_play.sc_arg); /* clear interrupts */ CH_WRITE1(sc, ch, AUVIA_RP_STAT, AUVIA_RPSTAT_INTR); i++; } return (i? 1 : 0); }
int auvia_halt_input(void *addr) { struct auvia_softc *sc = addr; struct auvia_softc_chan *ch = &(sc->sc_record); CH_WRITE1(sc, ch, AUVIA_RP_CONTROL, AUVIA_RPCTRL_TERMINATE); ch->sc_intr = NULL; return 0; }
static int auvia_trigger_output(void *addr, void *start, void *end, int blksize, void (*intr)(void *), void *arg, const audio_params_t *param) { struct auvia_softc *sc; struct auvia_softc_chan *ch; struct auvia_dma *p; sc = addr; ch = &(sc->sc_play); for (p = sc->sc_dmas; p && p->addr != start; p = p->next) continue; if (!p) panic("auvia_trigger_output: request with bad start " "address (%p)", start); if (auvia_build_dma_ops(sc, ch, p, start, end, blksize)) { return 1; } ch->sc_intr = intr; ch->sc_arg = arg; CH_WRITE4(sc, ch, AUVIA_RP_DMAOPS_BASE, ch->sc_dma_ops_dma->map->dm_segs[0].ds_addr); if (sc->sc_flags & AUVIA_FLAGS_VT8233) { if (ch->sc_base != VIA8233_MP_BASE) { CH_WRITE1(sc, ch, VIA8233_RP_DXS_LVOL, 0); CH_WRITE1(sc, ch, VIA8233_RP_DXS_RVOL, 0); } CH_WRITE1(sc, ch, AUVIA_RP_CONTROL, AUVIA_RPCTRL_START | AUVIA_RPCTRL_AUTOSTART | AUVIA_RPCTRL_STOP | AUVIA_RPCTRL_EOL | AUVIA_RPCTRL_FLAG); } else { CH_WRITE1(sc, ch, AUVIA_RP_MODE, ch->sc_reg); CH_WRITE1(sc, ch, AUVIA_RP_CONTROL, AUVIA_RPCTRL_START); } return 0; }
static int auvia_halt_output(void *addr) { struct auvia_softc *sc; struct auvia_softc_chan *ch; sc = addr; ch = &(sc->sc_play); CH_WRITE1(sc, ch, AUVIA_RP_CONTROL, AUVIA_RPCTRL_TERMINATE); ch->sc_intr = NULL; return 0; }
static int auvia_intr(void *arg) { struct auvia_softc *sc; struct auvia_softc_chan *ch; u_int8_t r; int rval; sc = arg; rval = 0; ch = &sc->sc_record; mutex_spin_enter(&sc->sc_intr_lock); r = CH_READ1(sc, ch, AUVIA_RP_STAT); if (r & AUVIA_RPSTAT_INTR) { if (sc->sc_record.sc_intr) sc->sc_record.sc_intr(sc->sc_record.sc_arg); /* clear interrupts */ CH_WRITE1(sc, ch, AUVIA_RP_STAT, AUVIA_RPSTAT_INTR); rval = 1; } ch = &sc->sc_play; r = CH_READ1(sc, ch, AUVIA_RP_STAT); if (r & AUVIA_RPSTAT_INTR) { if (sc->sc_play.sc_intr) sc->sc_play.sc_intr(sc->sc_play.sc_arg); /* clear interrupts */ CH_WRITE1(sc, ch, AUVIA_RP_STAT, AUVIA_RPSTAT_INTR); rval = 1; } mutex_spin_exit(&sc->sc_intr_lock); return rval; }
void auvia_set_params_sub(struct auvia_softc *sc, struct auvia_softc_chan *ch, struct audio_params *p) { u_int32_t v; u_int16_t regval; if (!(sc->sc_flags & AUVIA_FLAGS_VT8233)) { regval = (p->channels == 2 ? AUVIA_RPMODE_STEREO : 0) | (p->precision * p->factor == 16 ? AUVIA_RPMODE_16BIT : 0) | AUVIA_RPMODE_INTR_FLAG | AUVIA_RPMODE_INTR_EOL | AUVIA_RPMODE_AUTOSTART; ch->sc_reg = regval; } else if (ch->sc_base != VIA8233_MP_BASE) { v = CH_READ4(sc, ch, VIA8233_RP_RATEFMT); v &= ~(VIA8233_RATEFMT_48K | VIA8233_RATEFMT_STEREO | VIA8233_RATEFMT_16BIT); v |= VIA8233_RATEFMT_48K * (p->sample_rate / 20) / (48000 / 20); if (p->channels == 2) v |= VIA8233_RATEFMT_STEREO; if (p->precision == 16) v |= VIA8233_RATEFMT_16BIT; CH_WRITE4(sc, ch, VIA8233_RP_RATEFMT, v); } else { static const u_int32_t slottab[7] = { 0, 0xff000011, 0xff000021, 0, 0xff004321, 0, 0xff436521}; regval = (p->precision == 16 ? VIA8233_MP_FORMAT_16BIT : VIA8233_MP_FORMAT_8BIT) | (p->channels << 4); CH_WRITE1(sc, ch, VIA8233_OFF_MP_FORMAT, regval); CH_WRITE4(sc, ch, VIA8233_OFF_MP_STOP, slottab[p->channels]); } }