diff options
Diffstat (limited to 'sys/dev')
-rw-r--r-- | sys/dev/audio.c | 404 | ||||
-rw-r--r-- | sys/dev/audio_if.h | 12 | ||||
-rw-r--r-- | sys/dev/audiovar.h | 7 | ||||
-rw-r--r-- | sys/dev/isa/ad1848.c | 281 | ||||
-rw-r--r-- | sys/dev/isa/ad1848var.h | 20 | ||||
-rw-r--r-- | sys/dev/isa/aria.c | 81 | ||||
-rw-r--r-- | sys/dev/isa/files.isa | 6 | ||||
-rw-r--r-- | sys/dev/isa/gus.c | 130 | ||||
-rw-r--r-- | sys/dev/isa/gusreg.h | 23 | ||||
-rw-r--r-- | sys/dev/isa/pas.c | 11 | ||||
-rw-r--r-- | sys/dev/isa/pss.c | 227 | ||||
-rw-r--r-- | sys/dev/isa/sb.c | 191 | ||||
-rw-r--r-- | sys/dev/isa/sb_isa.c | 133 | ||||
-rw-r--r-- | sys/dev/isa/sbdsp.c | 454 | ||||
-rw-r--r-- | sys/dev/isa/sbdspvar.h | 26 | ||||
-rw-r--r-- | sys/dev/isa/sbreg.h | 13 | ||||
-rw-r--r-- | sys/dev/isa/sbvar.h | 36 | ||||
-rw-r--r-- | sys/dev/isa/wss.c | 28 | ||||
-rw-r--r-- | sys/dev/isa/wssreg.h | 7 |
19 files changed, 1083 insertions, 1007 deletions
diff --git a/sys/dev/audio.c b/sys/dev/audio.c index 85be437e16a..89431c8d919 100644 --- a/sys/dev/audio.c +++ b/sys/dev/audio.c @@ -1,4 +1,4 @@ -/* $OpenBSD: audio.c,v 1.9 1997/04/09 14:46:12 kstailey Exp $ */ +/* $OpenBSD: audio.c,v 1.10 1997/07/10 23:06:29 provos Exp $ */ /* $NetBSD: audio.c,v 1.26 1996/05/13 02:26:15 mycroft Exp $ */ /* @@ -87,6 +87,8 @@ #ifdef AUDIO_DEBUG #include <machine/stdarg.h> +void Dprintf __P((const char *, ...)); + void #ifdef __STDC__ Dprintf(const char *fmt, ...) @@ -112,10 +114,6 @@ int naudio; /* Count of attached hardware drivers */ int audio_blk_ms = AUDIO_BLK_MS; int audio_backlog = AUDIO_BACKLOG; -int audio_blocksize; - -/* A block of silence */ -char *auzero_block; struct audio_softc *audio_softc[NAUDIO]; @@ -128,6 +126,7 @@ int audio_read __P((dev_t, struct uio *, int)); int audio_write __P((dev_t, struct uio *, int)); int audio_ioctl __P((dev_t, int, caddr_t, int, struct proc *)); int audio_select __P((dev_t, int, struct proc *)); +int audio_mmap __P((dev_t, int, int)); int mixer_open __P((dev_t, int, int, struct proc *)); int mixer_close __P((dev_t, int, int, struct proc *)); @@ -140,9 +139,10 @@ void audiostartp __P((struct audio_softc *)); void audio_rint __P((void *)); void audio_pint __P((void *)); void audio_rpint __P((void *)); +int audio_check_format __P((u_int *, u_int *)); int audio_calc_blksize __P((struct audio_softc *)); -void audio_silence_fill __P((struct audio_softc *, u_char *, int)); +void audio_fill_silence __P((int, u_char *, int)); int audio_silence_copyout __P((struct audio_softc *, int, struct uio *)); void audio_alloc_auzero __P((struct audio_softc *, int)); @@ -170,7 +170,7 @@ audio_printsc(sc) printf("blksz %d sib %d ", sc->sc_blksize, sc->sc_smpl_in_blk); printf("sp50ms %d backlog %d\n", sc->sc_50ms, sc->sc_backlog); printf("hiwat %d lowat %d rblks %d\n", sc->sc_hiwat, sc->sc_lowat, - sc->sc_rblks); + sc->sc_rblks); } #endif @@ -211,9 +211,8 @@ audio_hardware_attach(hwp, hdlp) hwp->get_in_sr == 0 || hwp->set_out_sr == 0 || hwp->get_out_sr == 0 || - hwp->set_encoding == 0 || + hwp->set_format == 0 || hwp->get_encoding == 0 || - hwp->set_precision == 0 || hwp->get_precision == 0 || hwp->set_channels == 0 || hwp->get_channels == 0 || @@ -223,7 +222,6 @@ audio_hardware_attach(hwp, hdlp) hwp->set_in_port == 0 || hwp->get_in_port == 0 || hwp->commit_settings == 0 || - hwp->get_silence == 0 || hwp->start_output == 0 || hwp->start_input == 0 || hwp->halt_output == 0 || @@ -309,39 +307,34 @@ audioopen(dev, flags, ifmt, p) int flags, ifmt; struct proc *p; { - switch(AUDIODEV(dev)) { + + switch (AUDIODEV(dev)) { case SOUND_DEVICE: case AUDIO_DEVICE: - return audio_open(dev, flags, ifmt, p); - /*NOTREACHED*/ + return (audio_open(dev, flags, ifmt, p)); case MIXER_DEVICE: - return mixer_open(dev, flags, ifmt, p); - /*NOTREACHED*/ + return (mixer_open(dev, flags, ifmt, p)); default: - break; + return (ENXIO); } - return EIO; } -/* ARGSUSED */ int audioclose(dev, flags, ifmt, p) dev_t dev; int flags, ifmt; struct proc *p; { - switch(AUDIODEV(dev)) { + + switch (AUDIODEV(dev)) { case SOUND_DEVICE: case AUDIO_DEVICE: - return audio_close(dev, flags, ifmt, p); - /*NOTREACHED*/ + return (audio_close(dev, flags, ifmt, p)); case MIXER_DEVICE: - return mixer_close(dev, flags, ifmt, p); - /*NOTREACHED*/ + return (mixer_close(dev, flags, ifmt, p)); default: - break; + return (ENXIO); } - return EIO; } int @@ -350,18 +343,16 @@ audioread(dev, uio, ioflag) struct uio *uio; int ioflag; { - switch(AUDIODEV(dev)) { + + switch (AUDIODEV(dev)) { case SOUND_DEVICE: case AUDIO_DEVICE: - return audio_read(dev, uio, ioflag); - /*NOTREACHED*/ + return (audio_read(dev, uio, ioflag)); case MIXER_DEVICE: - return ENODEV; - /*NOTREACHED*/ + return (ENODEV); default: - break; + return (ENXIO); } - return EIO; } int @@ -370,18 +361,16 @@ audiowrite(dev, uio, ioflag) struct uio *uio; int ioflag; { - switch(AUDIODEV(dev)) { + + switch (AUDIODEV(dev)) { case SOUND_DEVICE: case AUDIO_DEVICE: - return audio_write(dev, uio, ioflag); - /*NOTREACHED*/ + return (audio_write(dev, uio, ioflag)); case MIXER_DEVICE: - return ENODEV; - /*NOTREACHED*/ + return (ENODEV); default: - break; + return (ENXIO); } - return EIO; } int @@ -392,38 +381,51 @@ audioioctl(dev, cmd, addr, flag, p) int flag; struct proc *p; { - switch(AUDIODEV(dev)) { + + switch (AUDIODEV(dev)) { case SOUND_DEVICE: case AUDIO_DEVICE: - return audio_ioctl(dev, cmd, addr, flag, p); - /*NOTREACHED*/ + return (audio_ioctl(dev, cmd, addr, flag, p)); case MIXER_DEVICE: - return mixer_ioctl(dev, cmd, addr, flag, p); - /*NOTREACHED*/ + return (mixer_ioctl(dev, cmd, addr, flag, p)); default: - break; + return (ENXIO); } - return EIO; } int -audioselect(dev, rw, p) +audioselect(dev, events, p) dev_t dev; - int rw; + int events; struct proc *p; { - switch(AUDIODEV(dev)) { + + switch (AUDIODEV(dev)) { case SOUND_DEVICE: case AUDIO_DEVICE: - return audio_select(dev, rw, p); - /*NOTREACHED*/ + return (audio_select(dev, events, p)); case MIXER_DEVICE: - return 1; - /*NOTREACHED*/ + return (0); default: - break; + return (0); + } +} + +int +audiommap(dev, off, prot) + dev_t dev; + int off, prot; +{ + + switch (AUDIODEV(dev)) { + case SOUND_DEVICE: + case AUDIO_DEVICE: + return (audio_mmap(dev, off, prot)); + case MIXER_DEVICE: + return (ENODEV); + default: + return (ENXIO); } - return EIO; } /* @@ -535,14 +537,12 @@ audio_open(dev, flags, ifmt, p) */ if (ISDEVAUDIO(dev)) { /* /dev/audio */ - hw->set_precision(sc->hw_hdl, 8); - hw->set_encoding(sc->hw_hdl, AUDIO_ENCODING_ULAW); + hw->set_format(sc->hw_hdl, AUDIO_ENCODING_ULAW, 8); hw->set_in_sr(sc->hw_hdl, 8000); hw->set_out_sr(sc->hw_hdl, 8000); hw->set_channels(sc->hw_hdl, 1); - sc->sc_pencoding = AUDIO_ENCODING_ULAW; - sc->sc_rencoding = AUDIO_ENCODING_ULAW; + sc->sc_pencoding = sc->sc_rencoding = AUDIO_ENCODING_ULAW; } /* @@ -554,15 +554,16 @@ audio_open(dev, flags, ifmt, p) if (hw->get_precision(sc->hw_hdl) == 0) panic("audio_open: hardware driver returned 0 for get_precision"); #endif - sc->sc_blksize = audio_blocksize = audio_calc_blksize(sc); + sc->sc_50ms = 50 * hw->get_out_sr(sc->hw_hdl) / 1000; + + sc->sc_blksize = audio_calc_blksize(sc); audio_alloc_auzero(sc, sc->sc_blksize); - - sc->sc_smpl_in_blk = audio_blocksize / + sc->sc_smpl_in_blk = sc->sc_blksize / (hw->get_precision(sc->hw_hdl) / NBBY); - sc->sc_50ms = 50 * hw->get_out_sr(sc->hw_hdl) / 1000; + audio_initbufs(sc); + sc->sc_backlog = audio_backlog; - audio_initbufs(sc); DPRINTF(("audio_open: rr.bp=%x-%x pr.bp=%x-%x\n", sc->rr.bp, sc->rr.ep, sc->pr.bp, sc->pr.ep)); @@ -605,6 +606,8 @@ audio_open(dev, flags, ifmt, p) audiostartr(sc); } } + /* Play all sample, and don't pad short writes by default */ + sc->sc_mode |= AUMODE_PLAY_ALL; splx(s); return (0); } @@ -700,6 +703,7 @@ audio_close(dev, flags, ifmt, p) if (flags&FWRITE) sc->sc_open &= ~AUOPEN_WRITE; + sc->sc_async = 0; splx(s); DPRINTF(("audio_close: done\n")); @@ -834,32 +838,46 @@ audio_calc_blksize(sc) } void -audio_silence_fill(sc, p, n) - struct audio_softc *sc; +audio_fill_silence(encoding, p, n) + int encoding; u_char *p; int n; { - struct audio_hw_if *hw = sc->hw_if; u_int auzero; - - auzero = hw->get_silence(sc->sc_pencoding); - + u_char *q; + + switch (encoding) { + case AUDIO_ENCODING_ULAW: + auzero = 0x7f; + break; + case AUDIO_ENCODING_ALAW: + auzero = 0x55; + break; + case AUDIO_ENCODING_ADPCM: /* is this right XXX */ + case AUDIO_ENCODING_PCM8: + case AUDIO_ENCODING_PCM16: + default: + auzero = 0; /* fortunately this works for both 8 and 16 bits */ + break; + } + q = p; while (--n >= 0) - *p++ = auzero; + *q++ = auzero; } +#define NSILENCE 128 /* An arbitrary even constant >= 2 */ int audio_silence_copyout(sc, n, uio) struct audio_softc *sc; int n; struct uio *uio; { - struct audio_hw_if *hw = sc->hw_if; struct iovec *iov; int error = 0; - u_int auzero; + u_char zerobuf[NSILENCE]; + int k; - auzero = hw->get_silence(sc->sc_rencoding); + audio_fill_silence(sc->sc_rencoding, zerobuf, NSILENCE); while (n > 0 && uio->uio_resid) { iov = uio->uio_iov; @@ -868,22 +886,23 @@ audio_silence_copyout(sc, n, uio) uio->uio_iovcnt--; continue; } + k = min(min(n, iov->iov_len), NSILENCE); switch (uio->uio_segflg) { case UIO_USERSPACE: - error = copyout(&auzero, iov->iov_base, 1); + error = copyout(zerobuf, iov->iov_base, k); if (error) return (error); break; case UIO_SYSSPACE: - bcopy(&auzero, iov->iov_base, 1); + bcopy(zerobuf, iov->iov_base, k); break; } - iov->iov_base++; - iov->iov_len--; - uio->uio_resid--; - uio->uio_offset++; - n--; + iov->iov_base += k; + iov->iov_len -= k; + uio->uio_resid -= k; + uio->uio_offset += k; + n -= k; } return (error); } @@ -894,26 +913,19 @@ audio_alloc_auzero(sc, bs) int bs; { struct audio_hw_if *hw = sc->hw_if; - u_char *p, silence; - int i; - - if (auzero_block) - free(auzero_block, M_DEVBUF); - auzero_block = malloc(bs, M_DEVBUF, M_WAITOK); + if (sc->auzero_block) + free(sc->auzero_block, M_DEVBUF); + + sc->auzero_block = malloc(bs, M_DEVBUF, M_WAITOK); #ifdef DIAGNOSTIC - if (auzero_block == 0) { + if (sc->auzero_block == 0) { panic("audio_alloc_auzero: malloc auzero_block failed"); } #endif - silence = hw->get_silence(sc->sc_pencoding); - - p = auzero_block; - for (i = 0; i < bs; i++) - *p++ = silence; - + audio_fill_silence(sc->sc_pencoding, sc->auzero_block, bs); if (hw->sw_encode) - hw->sw_encode(sc->hw_hdl, sc->sc_pencoding, auzero_block, bs); + hw->sw_encode(sc->hw_hdl, sc->sc_pencoding, sc->auzero_block, bs); } @@ -945,6 +957,32 @@ audio_write(dev, uio, ioflag) error = 0; while (uio->uio_resid > 0) { + if (cb->fill > 0) { + if (sc->sc_pbus == 0) { + /* playing has stopped, ignore fill */ + cb->fill = 0; + } else { + /* Write samples in the silence fill space. + * We don't know where the DMA is + * happening in the buffer, but if we + * are lucky we will fill the buffer before + * playing has reached the point we move to. + * If we are unlucky some sample will + * not be played. + */ + cc = min(cb->fill, uio->uio_resid); + error = uiomove(cb->otp, cc, uio); + if (error == 0) { + if (hw->sw_encode) + hw->sw_encode(sc->hw_hdl, + sc->sc_pencoding, cb->otp, + cc); + cb->fill -= cc; + cb->otp += cc; + } + continue; + } + } if (cb->nblk >= sc->sc_hiwat) { do { DPRINTF(("audio_write: nblk=%d hiwat=%d lowat=%d\n", cb->nblk, sc->sc_hiwat, sc->sc_lowat)); @@ -979,7 +1017,7 @@ audio_write(dev, uio, ioflag) cb->nblk = sc->sc_backlog; cb->tp = cb->hp + sc->sc_backlog * blocksize; splx(s); - audio_silence_fill(sc, cb->hp, sc->sc_backlog * blocksize); + audio_fill_silence(sc->sc_pencoding, cb->hp, sc->sc_backlog * blocksize); } #endif /* Calculate sample number of first sample in block we write */ @@ -1016,7 +1054,9 @@ audio_write(dev, uio, ioflag) /* fill with audio silence */ tp += cc; cc = blocksize - cc; - audio_silence_fill(sc, tp, cc); + cb->fill = cc; + cb->otp = tp; + audio_fill_silence(sc->sc_pencoding, tp, cc); DPRINTF(("audio_write: auzero 0x%x %d 0x%x\n", tp, cc, *(int *)tp)); tp += cc; @@ -1034,9 +1074,9 @@ audio_write(dev, uio, ioflag) break; } - if (hw->sw_encode) { - hw->sw_encode(sc->hw_hdl, sc->sc_pencoding, cb->tp, blocksize); - } + if (hw->sw_encode) + hw->sw_encode(sc->hw_hdl, sc->sc_pencoding, cb->tp, + blocksize); /* wrap the ring buffer if at end */ s = splaudio(); @@ -1226,6 +1266,15 @@ audio_select(dev, rw, p) return (0); } +int +audio_mmap(dev, off, prot) + dev_t dev; + int off, prot; +{ + /* XXX placeholder */ + return (-1); +} + void audiostartr(sc) struct audio_softc *sc; @@ -1341,11 +1390,11 @@ audio_pint(v) cb->cb_drops++; #ifdef AUDIO_DEBUG if (audiodebug > 1) - Dprintf("audio_pint: drops=%d auzero %d 0x%x\n", cb->cb_drops, cc, *(int *)auzero_block); + Dprintf("audio_pint: drops=%d auzero %d 0x%x\n", cb->cb_drops, cc, *(int *)sc->auzero_block); #endif psilence: error = hw->start_output(sc->hw_hdl, - auzero_block, cc, + sc->auzero_block, cc, audio_pint, (void *)sc); if (error) { DPRINTF(("audio_pint zero failed: %d\n", error)); @@ -1440,15 +1489,52 @@ audio_rint(v) } int +audio_check_format(encodingp, precisionp) + u_int *encodingp, *precisionp; +{ + + if (*encodingp == AUDIO_ENCODING_LINEAR) + switch (*precisionp) { + case 8: + *encodingp = AUDIO_ENCODING_PCM8; + return (0); + case 16: + *encodingp = AUDIO_ENCODING_PCM16; + return (0); + default: + return (EINVAL); + } + + switch (*encodingp) { + case AUDIO_ENCODING_ULAW: + case AUDIO_ENCODING_ALAW: + case AUDIO_ENCODING_PCM8: + case AUDIO_ENCODING_ADPCM: + if (*precisionp != 8) + return (EINVAL); + break; + case AUDIO_ENCODING_PCM16: + if (*precisionp != 16) + return (EINVAL); + break; + default: + return (EINVAL); + } + + return (0); +} + +int audiosetinfo(sc, ai) struct audio_softc *sc; struct audio_info *ai; { struct audio_prinfo *r = &ai->record, *p = &ai->play; - int cleared = 0; - int bsize, bps, error = 0; + int cleared = 0, init = 0; + int bsize, error = 0; struct audio_hw_if *hw = sc->hw_if; mixer_ctrl_t ct; + int s; if (hw == 0) /* HW has not attached */ return(ENXIO); @@ -1457,98 +1543,91 @@ audiosetinfo(sc, ai) if (!cleared) audio_clear(sc); cleared = 1; + error = hw->set_out_sr(sc->hw_hdl, p->sample_rate); if (error) return(error); + sc->sc_50ms = 50 * hw->get_out_sr(sc->hw_hdl) / 1000; + init = 1; } if (r->sample_rate != ~0) { if (!cleared) audio_clear(sc); cleared = 1; + error = hw->set_in_sr(sc->hw_hdl, r->sample_rate); if (error) return(error); + sc->sc_50ms = 50 * hw->get_in_sr(sc->hw_hdl) / 1000; + init = 1; } - if (p->encoding != ~0) { + if (p->encoding != ~0 || p->precision != ~0) { if (!cleared) audio_clear(sc); cleared = 1; - error = hw->set_encoding(sc->hw_hdl, p->encoding); + + if (p->encoding == ~0) + p->encoding = hw->get_encoding(sc->hw_hdl); + if (p->precision == ~0) + p->precision = hw->get_precision(sc->hw_hdl); + error = audio_check_format(&p->encoding, &p->precision); if (error) return(error); - sc->sc_pencoding = p->encoding; - } - if (r->encoding != ~0) { - if (!cleared) - audio_clear(sc); - cleared = 1; - error = hw->set_encoding(sc->hw_hdl, r->encoding); + error = hw->set_format(sc->hw_hdl, p->encoding, p->precision); if (error) return(error); - sc->sc_rencoding = r->encoding; - } - if (p->precision != ~0) { + + sc->sc_pencoding = p->encoding; + init = 1; + } + if (r->encoding != ~0 || r->precision != ~0) { if (!cleared) audio_clear(sc); cleared = 1; - error = hw->set_precision(sc->hw_hdl, p->precision); + + if (r->encoding == ~0) + r->encoding = hw->get_encoding(sc->hw_hdl); + if (r->precision == ~0) + r->precision = hw->get_precision(sc->hw_hdl); + error = audio_check_format(&r->encoding, &r->precision); if (error) return(error); - - sc->sc_blksize = audio_blocksize = audio_calc_blksize(sc); - audio_alloc_auzero(sc, sc->sc_blksize); - bps = hw->get_precision(sc->hw_hdl) / NBBY; - sc->sc_smpl_in_blk = sc->sc_blksize / bps; - audio_initbufs(sc); - } - if (r->precision != ~0) { - if (!cleared) - audio_clear(sc); - cleared = 1; - error = hw->set_precision(sc->hw_hdl, r->precision); + error = hw->set_format(sc->hw_hdl, r->encoding, r->precision); if (error) return(error); - - sc->sc_blksize = audio_blocksize = audio_calc_blksize(sc); - audio_alloc_auzero(sc, sc->sc_blksize); - bps = hw->get_precision(sc->hw_hdl) / NBBY; - sc->sc_smpl_in_blk = sc->sc_blksize / bps; - audio_initbufs(sc); + + sc->sc_rencoding = r->encoding; + init = 1; } if (p->channels != ~0) { if (!cleared) audio_clear(sc); cleared = 1; + error = hw->set_channels(sc->hw_hdl, p->channels); if (error) return(error); - sc->sc_blksize = audio_blocksize = audio_calc_blksize(sc); - audio_alloc_auzero(sc, sc->sc_blksize); - bps = hw->get_precision(sc->hw_hdl) / NBBY; - sc->sc_smpl_in_blk = sc->sc_blksize / bps; - audio_initbufs(sc); + init = 1; } if (r->channels != ~0) { if (!cleared) audio_clear(sc); cleared = 1; + error = hw->set_channels(sc->hw_hdl, r->channels); if (error) return(error); - sc->sc_blksize = audio_blocksize = audio_calc_blksize(sc); - audio_alloc_auzero(sc, sc->sc_blksize); - bps = hw->get_precision(sc->hw_hdl) / NBBY; - sc->sc_smpl_in_blk = sc->sc_blksize / bps; - audio_initbufs(sc); + init = 1; } if (p->port != ~0) { if (!cleared) audio_clear(sc); cleared = 1; + error = hw->set_out_port(sc->hw_hdl, p->port); if (error) return(error); @@ -1557,6 +1636,7 @@ audiosetinfo(sc, ai) if (!cleared) audio_clear(sc); cleared = 1; + error = hw->set_in_port(sc->hw_hdl, r->port); if (error) return(error); @@ -1583,27 +1663,28 @@ audiosetinfo(sc, ai) if (p->pause != (u_char)~0) { sc->pr.cb_pause = p->pause; if (!p->pause) { - int s = splaudio(); + s = splaudio(); audiostartp(sc); - splx(s); + splx(s); } } if (r->pause != (u_char)~0) { sc->rr.cb_pause = r->pause; if (!r->pause) { - int s = splaudio(); + s = splaudio(); audiostartr(sc); - splx(s); + splx(s); } } - if (ai->blocksize != ~0) { /* Explicitly specified, possibly */ - /* overriding changes done above. */ + if (ai->blocksize != ~0) { + /* Block size specified explicitly. */ if (!cleared) audio_clear(sc); cleared = 1; + if (ai->blocksize == 0) - bsize = audio_blocksize; + bsize = sc->sc_blksize; else if (ai->blocksize > AU_RING_SIZE/2) bsize = AU_RING_SIZE/2; else @@ -1611,12 +1692,21 @@ audiosetinfo(sc, ai) bsize = hw->round_blocksize(sc->hw_hdl, bsize); if (bsize > AU_RING_SIZE) bsize = AU_RING_SIZE; - ai->blocksize = sc->sc_blksize = bsize; + + sc->sc_blksize = bsize; + init = 1; + } else if (init) { + /* Block size calculated from other parameter changes. */ + sc->sc_blksize = audio_calc_blksize(sc); + } + + if (init) { audio_alloc_auzero(sc, sc->sc_blksize); - bps = hw->get_precision(sc->hw_hdl) / NBBY; - sc->sc_smpl_in_blk = bsize / bps; + sc->sc_smpl_in_blk = sc->sc_blksize / + (hw->get_precision(sc->hw_hdl) / NBBY); audio_initbufs(sc); } + if (ai->hiwat != ~0) { if ((unsigned)ai->hiwat > sc->pr.maxblk) ai->hiwat = sc->pr.maxblk; @@ -1637,6 +1727,7 @@ audiosetinfo(sc, ai) if (!cleared) audio_clear(sc); cleared = 1; + sc->sc_mode = ai->mode; if (sc->sc_mode & AUMODE_PLAY) { audio_init_play(sc); @@ -1646,12 +1737,13 @@ audiosetinfo(sc, ai) if (sc->sc_mode & AUMODE_RECORD) audio_init_record(sc); } + error = hw->commit_settings(sc->hw_hdl); if (error) return (error); if (cleared) { - int s = splaudio(); + s = splaudio(); if (sc->sc_mode & AUMODE_PLAY) audiostartp(sc); if (sc->sc_mode & AUMODE_RECORD) diff --git a/sys/dev/audio_if.h b/sys/dev/audio_if.h index 9ee9b45ae1d..ac6c67440ce 100644 --- a/sys/dev/audio_if.h +++ b/sys/dev/audio_if.h @@ -1,4 +1,4 @@ -/* $OpenBSD: audio_if.h,v 1.4 1996/04/18 23:46:58 niklas Exp $ */ +/* $OpenBSD: audio_if.h,v 1.5 1997/07/10 23:06:30 provos Exp $ */ /* $NetBSD: audio_if.h,v 1.7 1996/03/07 15:00:10 christos Exp $ */ /* @@ -53,14 +53,11 @@ struct audio_hw_if { u_long (*get_out_sr)__P((void *)); /* Encoding. */ + /* Precision = bits/sample, usually 8 or 16 */ /* XXX should we have separate in/out? */ int (*query_encoding)__P((void *, struct audio_encoding *)); - int (*set_encoding)__P((void *, u_int)); + int (*set_format)__P((void *, u_int, u_int)); int (*get_encoding)__P((void *)); - - /* Precision = bits/sample, usually 8 or 16 */ - /* XXX should we have separate in/out? */ - int (*set_precision)__P((void *, u_int)); int (*get_precision)__P((void *)); /* Channels - mono(1), stereo(2) */ @@ -86,9 +83,6 @@ struct audio_hw_if { */ int (*commit_settings)__P((void *)); - /* Return silence value for encoding */ - u_int (*get_silence)__P((int)); - /* Software en/decode functions, set if SW coding required by HW */ void (*sw_encode)__P((void *, int, u_char *, int)); void (*sw_decode)__P((void *, int, u_char *, int)); diff --git a/sys/dev/audiovar.h b/sys/dev/audiovar.h index ca1d6321c06..4cda887e095 100644 --- a/sys/dev/audiovar.h +++ b/sys/dev/audiovar.h @@ -1,4 +1,4 @@ -/* $OpenBSD: audiovar.h,v 1.3 1996/03/02 00:29:21 niklas Exp $ */ +/* $OpenBSD: audiovar.h,v 1.4 1997/07/10 23:06:30 provos Exp $ */ /* $NetBSD: audiovar.h,v 1.7 1996/02/20 10:00:33 mycroft Exp $ */ /* @@ -79,6 +79,9 @@ struct audio_buffer { u_short cb_pause; /* io paused */ u_long cb_drops; /* missed samples from over/underrun */ u_long cb_pdrops; /* paused samples */ + + int fill; /* number of silence pad bytes */ + u_char *otp; /* point where silence padding started */ }; /* @@ -103,6 +106,8 @@ struct audio_softc { /* Ring buffers, separate for record and play. */ struct audio_buffer rr; /* Record ring */ struct audio_buffer pr; /* Play ring */ + + u_char *auzero_block; /* a block of silence */ u_char sc_rbus; /* input dma in progress */ u_char sc_pbus; /* output dma in progress */ diff --git a/sys/dev/isa/ad1848.c b/sys/dev/isa/ad1848.c index bea11d59d2f..ff674851a92 100644 --- a/sys/dev/isa/ad1848.c +++ b/sys/dev/isa/ad1848.c @@ -1,4 +1,4 @@ -/* $OpenBSD: ad1848.c,v 1.7 1996/08/23 20:13:13 deraadt Exp $ */ +/* $OpenBSD: ad1848.c,v 1.8 1997/07/10 23:06:31 provos Exp $ */ /* $NetBSD: ad1848.c,v 1.10 1996/04/29 20:02:32 christos Exp $ */ /* @@ -107,29 +107,29 @@ int ad1848debug = 0; * Initial values for the indirect registers of CS4248/AD1848. */ static int ad1848_init_values[] = { - /* Left Input Control */ + /* Left Input Control */ GAIN_12|INPUT_MIC_GAIN_ENABLE, - /* Right Input Control */ + /* Right Input Control */ GAIN_12|INPUT_MIC_GAIN_ENABLE, ATTEN_12, /* Left Aux #1 Input Control */ ATTEN_12, /* Right Aux #1 Input Control */ ATTEN_12, /* Left Aux #2 Input Control */ ATTEN_12, /* Right Aux #2 Input Control */ /* bits 5-0 are attenuation select */ - 0x19, /* Left DAC output Control */ - 0x19, /* Right DAC output Control */ - /* Clock and Data Format */ + ATTEN_12, /* Left DAC output Control */ + ATTEN_12, /* Right DAC output Control */ + /* Clock and Data Format */ CLOCK_XTAL1|FMT_PCM8, - /* Interface Config */ + /* Interface Config */ SINGLE_DMA|AUTO_CAL_ENABLE, INTERRUPT_ENABLE, /* Pin control */ 0x00, /* Test and Init */ - 0xca, /* Misc control */ + MODE2, /* Misc control */ ATTEN_0<<2, /* Digital Mix Control */ 0, /* Upper base Count */ 0, /* Lower base Count */ - /* Thse are for CS4231 only (additional registers): */ + /* These are for CS4231 &c. only (additional registers): */ 0, /* Alt feature 1 */ 0, /* Alt feature 2 */ ATTEN_12, /* Left line in */ @@ -140,18 +140,16 @@ static int ad1848_init_values[] = { 0, /* unused */ 0, /* IRQ status */ 0, /* unused */ - /* Mono input (mic) Control */ + /* Mono input (mic) Control */ MONO_INPUT_MUTE|ATTEN_6, /* mute mic by default */ 0, /* unused */ 0, /* record format */ 0, /* upper record count */ - 0, /* lower record count */ - + 0 /* lower record count */ }; void ad1848_reset __P((struct ad1848_softc *)); -int ad1848_set_speed __P((struct ad1848_softc *, int)); -int ad1848_set_format __P((struct ad1848_softc *, int, int)); +int ad1848_set_speed __P((struct ad1848_softc *, u_long)); void ad1848_mute_monitor __P((void *, int)); static int ad_read __P((struct ad1848_softc *, int)); @@ -242,6 +240,8 @@ wait_for_calibration(sc) } #ifdef AUDIO_DEBUG +void ad1848_dump_regs __P((struct ad1848_softc *)); + void ad1848_dump_regs(sc) struct ad1848_softc *sc; @@ -249,18 +249,19 @@ ad1848_dump_regs(sc) int i; u_char r; - printf("ad1848 status=%x", inb(sc->sc_iobase+AD1848_STATUS)); + printf("ad1848 status=%02x", inb(sc->sc_iobase+AD1848_STATUS)); printf(" regs: "); for (i = 0; i < 16; i++) { r = ad_read(sc, i); - printf("%x ", r); + printf("%02x ", r); } - if (sc->mode == 2) + if (sc->mode == 2) { for (i = 16; i < 32; i++) { r = ad_read(sc, i); - printf("%x ", r); + printf("%02x ", r); } - printf("\n"); + printf("\n"); + } } #endif @@ -302,7 +303,9 @@ ad1848_probe(sc) int i; if (!AD1848_BASE_VALID(iobase)) { - printf("ad1848: configured iobase %x invalid\n", iobase); +#ifdef AUDIO_DEBUG + printf("ad1848: configured iobase %04x invalid\n", iobase); +#endif return 0; } @@ -487,24 +490,18 @@ ad1848_attach(sc) ad_write(sc, i, ad1848_init_values[i]); /* ...and additional CS4231 stuff too */ if (sc->mode == 2) { -#if 0 - ad_write(sc, SP_INTERFACE_CONFIG, 0); /* disable SINGLE_DMA feature */ -#else - /* XXX SINGLE_DMA is cleared in ad1848_reset(), due to #if 0 */ -#endif - for (i = 0x10; i <= 0x1F; i++) + ad_write(sc, SP_INTERFACE_CONFIG, 0); /* disable SINGLE_DMA */ + for (i = 0x10; i <= 0x1f; i++) if (ad1848_init_values[i] != 0) ad_write(sc, i, ad1848_init_values[i]); } ad1848_reset(sc); - /* Set default encoding (ULAW) */ - sc->sc_irate = sc->sc_orate = 8000; - sc->precision = 8; - sc->channels = 1; - sc->encoding = AUDIO_ENCODING_ULAW; - (void) ad1848_set_in_sr(sc, sc->sc_irate); - (void) ad1848_set_out_sr(sc, sc->sc_orate); + /* Set default parameters (mono, 8KHz, ULAW) */ + (void) ad1848_set_channels(sc, 1); + (void) ad1848_set_speed(sc, 8000); + (void) ad1848_set_format(sc, AUDIO_ENCODING_ULAW, 8); + (void) ad1848_commit_settings(sc); /* Set default gains */ (void) ad1848_set_rec_gain(sc, &vol_mid); @@ -917,9 +914,7 @@ ad1848_set_in_sr(addr, sr) DPRINTF(("ad1848_set_in_sr: %d\n", sr)); - sc->sc_irate = sc->sc_orate = ad1848_set_speed(sc, sr); - - return(0); + return (ad1848_set_speed(sc, sr)); } u_long @@ -928,7 +923,7 @@ ad1848_get_in_sr(addr) { register struct ad1848_softc *sc = addr; - return(sc->sc_irate); + return (sc->speed); } int @@ -940,9 +935,7 @@ ad1848_set_out_sr(addr, sr) DPRINTF(("ad1848_set_out_sr: %d\n", sr)); - sc->sc_irate = sc->sc_orate = ad1848_set_speed(sc, sr); - - return(0); + return (ad1848_set_speed(sc, sr)); } u_long @@ -951,7 +944,7 @@ ad1848_get_out_sr(addr) { register struct ad1848_softc *sc = addr; - return(sc->sc_orate); + return (sc->speed); } int @@ -984,29 +977,38 @@ ad1848_query_encoding(addr, fp) } int -ad1848_set_encoding(addr, enc) +ad1848_set_format(addr, encoding, precision) void *addr; - u_int enc; + u_int encoding, precision; { register struct ad1848_softc *sc = addr; - - DPRINTF(("ad1848_set_encoding: %d\n", enc)); - - if (sc->encoding != AUDIO_ENCODING_PCM8 && - sc->encoding != AUDIO_ENCODING_PCM16 && - sc->encoding != AUDIO_ENCODING_ALAW && - sc->encoding != AUDIO_ENCODING_ULAW) { + static u_char format2bits[] = { + /* AUDIO_ENCODING_NONE */ 0, + /* AUDIO_ENCODING_ULAW */ FMT_ULAW >> 5, + /* AUDIO_ENCODING_ALAW */ FMT_ALAW >> 5, + /* AUDIO_ENCODING_PCM16 */ FMT_TWOS_COMP >> 5, + /* AUDIO_ENCODING_PCM8 */ FMT_PCM8 >> 5, + /* AUDIO_ENCODING_ADPCM */ 0, + }; - sc->encoding = AUDIO_ENCODING_PCM8; + DPRINTF(("ad1848_set_format: encoding=%d precision=%d\n", encoding, precision)); + + switch (encoding) { + case AUDIO_ENCODING_ULAW: + case AUDIO_ENCODING_ALAW: + case AUDIO_ENCODING_PCM16: + case AUDIO_ENCODING_PCM8: + break; + default: return (EINVAL); } - sc->encoding = ad1848_set_format(sc, enc, sc->precision); + sc->encoding = encoding; + sc->precision = precision; + sc->format_bits = format2bits[encoding]; + sc->need_commit = 1; - if (sc->encoding == -1) { - sc->encoding = AUDIO_ENCODING_PCM8; - return (EINVAL); - } + DPRINTF(("ad1848_set_format: bits=%x\n", sc->format_bits)); return (0); } @@ -1017,27 +1019,7 @@ ad1848_get_encoding(addr) { register struct ad1848_softc *sc = addr; - return(sc->encoding); -} - -int -ad1848_set_precision(addr, prec) - void *addr; - u_int prec; -{ - register struct ad1848_softc *sc = addr; - - DPRINTF(("ad1848_set_precision: %d\n", prec)); - - sc->encoding = ad1848_set_format(sc, sc->encoding, prec); - if (sc->encoding == -1) { - sc->encoding = AUDIO_ENCODING_PCM16; - sc->precision = 16; - return (EINVAL); - } - sc->precision = prec; - - return (0); + return (sc->encoding); } int @@ -1046,24 +1028,25 @@ ad1848_get_precision(addr) { register struct ad1848_softc *sc = addr; - return(sc->precision); + return (sc->precision); } int -ad1848_set_channels(addr, chans) +ad1848_set_channels(addr, channels) void *addr; - int chans; + int channels; { register struct ad1848_softc *sc = addr; - DPRINTF(("ad1848_set_channels: %d\n", chans)); + DPRINTF(("ad1848_set_channels: %d\n", channels)); - if (chans < 1 || chans > 2) - return(EINVAL); + if (channels != 1 && channels != 2) + return (EINVAL); - sc->channels = chans; + sc->channels = channels; + sc->need_commit = 1; - return(0); + return (0); } int @@ -1072,7 +1055,7 @@ ad1848_get_channels(addr) { register struct ad1848_softc *sc = addr; - return(sc->channels); + return (sc->channels); } int @@ -1128,46 +1111,16 @@ ad1848_round_blocksize(addr, blk) sc->sc_lastcc = -1; - /* Higher speeds need bigger blocks to avoid popping and silence gaps. */ - if ((sc->sc_orate > 8000 || sc->sc_irate > 8000) && blk < NBPG/2) - blk = NBPG/2; - /* don't try to DMA too much at once, though. */ + /* Don't try to DMA too much at once. */ if (blk > NBPG) blk = NBPG; - if (sc->channels == 2) - return (blk & ~1); /* must be even to preserve stereo separation */ - else - return(blk); /* Anything goes :-) */ -} + /* Round to a multiple of the sample size. */ + blk &= -(sc->channels * sc->precision / 8); -u_int -ad1848_get_silence(enc) - int enc; -{ -#define ULAW_SILENCE 0x7f -#define ALAW_SILENCE 0x55 -#define LINEAR_SILENCE 0 - u_int auzero; - - switch (enc) { - case AUDIO_ENCODING_ULAW: - auzero = ULAW_SILENCE; - break; - case AUDIO_ENCODING_ALAW: - auzero = ALAW_SILENCE; - break; - case AUDIO_ENCODING_PCM8: - case AUDIO_ENCODING_PCM16: - default: - auzero = LINEAR_SILENCE; - break; - } - - return(auzero); + return (blk); } - int ad1848_open(sc, dev, flags) struct ad1848_softc *sc; @@ -1233,7 +1186,12 @@ ad1848_commit_settings(addr) struct ad1848_softc *sc = addr; int timeout; u_char fs; - int s = splaudio(); + int s; + + if (!sc->need_commit) + return 0; + + s = splaudio(); ad1848_mute_monitor(sc, 1); @@ -1293,6 +1251,7 @@ ad1848_commit_settings(addr) splx(s); + sc->need_commit = 0; return 0; } @@ -1300,20 +1259,15 @@ void ad1848_reset(sc) register struct ad1848_softc *sc; { -#if 0 u_char r; -#endif DPRINTF(("ad1848_reset\n")); /* Clear the PEN and CEN bits */ -#if 0 r = ad_read(sc, SP_INTERFACE_CONFIG); r &= ~(CAPTURE_ENABLE|PLAYBACK_ENABLE); ad_write(sc, SP_INTERFACE_CONFIG, r); -#else - ad_write(sc, SP_INTERFACE_CONFIG, 0); -#endif + if (sc->mode == 2) { outb(sc->sc_iobase+AD1848_IADDR, CS_IRQ_STATUS); outb(sc->sc_iobase+AD1848_IDATA, 0); @@ -1329,7 +1283,7 @@ ad1848_reset(sc) int ad1848_set_speed(sc, arg) register struct ad1848_softc *sc; - int arg; + u_long arg; { /* * The sampling speed is encoded in the least significant nible of I8. The @@ -1345,21 +1299,21 @@ ad1848_set_speed(sc, arg) } speed_struct; static speed_struct speed_table[] = { - {5510, (0 << 1) | 1}, - {5510, (0 << 1) | 1}, - {6620, (7 << 1) | 1}, - {8000, (0 << 1) | 0}, - {9600, (7 << 1) | 0}, - {11025, (1 << 1) | 1}, - {16000, (1 << 1) | 0}, - {18900, (2 << 1) | 1}, - {22050, (3 << 1) | 1}, - {27420, (2 << 1) | 0}, - {32000, (3 << 1) | 0}, - {33075, (6 << 1) | 1}, - {37800, (4 << 1) | 1}, - {44100, (5 << 1) | 1}, - {48000, (6 << 1) | 0} + {5510, (0 << 1) | 1}, + {5510, (0 << 1) | 1}, + {6620, (7 << 1) | 1}, + {8000, (0 << 1) | 0}, + {9600, (7 << 1) | 0}, + {11025, (1 << 1) | 1}, + {16000, (1 << 1) | 0}, + {18900, (2 << 1) | 1}, + {22050, (3 << 1) | 1}, + {27420, (2 << 1) | 0}, + {32000, (3 << 1) | 0}, + {33075, (6 << 1) | 1}, + {37800, (4 << 1) | 1}, + {44100, (5 << 1) | 1}, + {48000, (6 << 1) | 0} }; int i, n, selected = -1; @@ -1393,46 +1347,9 @@ ad1848_set_speed(sc, arg) sc->speed = speed_table[selected].speed; sc->speed_bits = speed_table[selected].bits; + sc->need_commit = 1; - return sc->speed; -} - -int -ad1848_set_format(sc, fmt, prec) - register struct ad1848_softc *sc; - int fmt, prec; -{ - static u_char format2bits[] = { - /* AUDIO_ENCODING_ULAW */ FMT_ULAW >> 5, - /* AUDIO_ENCODING_ALAW */ FMT_ALAW >> 5, - /* AUDIO_ENCODING_PCM16 */ FMT_TWOS_COMP >> 5, - /* AUDIO_ENCODING_PCM8 */ FMT_PCM8 >> 5 - }; - - DPRINTF(("ad1848_set_format: fmt=%d prec=%d\n", fmt, prec)); - - /* If not linear; force prec to 8bits */ - if (fmt != AUDIO_ENCODING_PCM16 && prec == 16) - prec = 8; - - if (fmt < AUDIO_ENCODING_ULAW || fmt > AUDIO_ENCODING_PCM8) - goto nogood; - - if (prec != 8 && prec != 16) - goto nogood; - - sc->format_bits = format2bits[fmt-1]; - - if (fmt == AUDIO_ENCODING_PCM16 && prec == 8) - sc->format_bits = FMT_PCM8 >> 5; /* signed vs. unsigned samples? */ - - DPRINTF(("ad1848_set_format: bits=%x\n", sc->format_bits)); - - return fmt; - - nogood: - sc->format_bits = 0; - return -1; + return (0); } /* diff --git a/sys/dev/isa/ad1848var.h b/sys/dev/isa/ad1848var.h index 30ce614cf42..a9e9d29dfc5 100644 --- a/sys/dev/isa/ad1848var.h +++ b/sys/dev/isa/ad1848var.h @@ -64,19 +64,11 @@ struct ad1848_softc { int sc_drq; /* DMA */ int sc_recdrq; /* record/capture DMA */ - u_long sc_irate; /* Sample rate for input */ - u_long sc_orate; /* ...and output */ - /* We keep track of these */ struct ad1848_volume rec_gain, aux1_gain, aux2_gain, out_gain, mon_gain, line_gain, mono_gain; - u_int encoding; /* ulaw/linear -- keep track */ - u_int precision; /* 8/16 bits */ - int rec_port; /* recording port */ - int channels; - /* ad1848 */ u_char MCE_bit; char mic_gain_on; /* CS4231 only */ @@ -84,9 +76,14 @@ struct ad1848_softc { char *chip_name; int mode; - int speed; + u_long speed; + u_int encoding; /* ulaw/linear -- keep track */ + u_int precision; /* 8/16 bits */ + int channels; + u_char speed_bits; u_char format_bits; + u_char need_commit; u_long sc_interrupts; /* number of interrupts taken */ void (*sc_intr)(void *); /* dma completion intr handler */ @@ -115,9 +112,8 @@ u_long ad1848_get_in_sr __P((void *)); int ad1848_set_out_sr __P((void *, u_long)); u_long ad1848_get_out_sr __P((void *)); int ad1848_query_encoding __P((void *, struct audio_encoding *)); -int ad1848_set_encoding __P((void *, u_int)); +int ad1848_set_format __P((void *, u_int, u_int)); int ad1848_get_encoding __P((void *)); -int ad1848_set_precision __P((void *, u_int)); int ad1848_get_precision __P((void *)); int ad1848_set_channels __P((void *, int)); int ad1848_get_channels __P((void *)); @@ -129,8 +125,6 @@ int ad1848_dma_input __P((void *, void *, int, void (*)(void *), void*)); int ad1848_commit_settings __P((void *)); -u_int ad1848_get_silence __P((int)); - int ad1848_halt_in_dma __P((void *)); int ad1848_halt_out_dma __P((void *)); int ad1848_cont_in_dma __P((void *)); diff --git a/sys/dev/isa/aria.c b/sys/dev/isa/aria.c index 3e35a8f6791..c965453619c 100644 --- a/sys/dev/isa/aria.c +++ b/sys/dev/isa/aria.c @@ -1,4 +1,4 @@ -/* $OpenBSD: aria.c,v 1.2 1996/08/01 15:29:53 deraadt Exp $ */ +/* $OpenBSD: aria.c,v 1.3 1997/07/10 23:06:32 provos Exp $ */ /* * Copyright (c) 1995, 1996 Roland C. Dowdeswell. All rights reserved. @@ -122,7 +122,7 @@ struct aria_softc { u_int spkr_state; /* non-null is on */ u_long sc_rate; /* Sample rate for input and output */ - u_int encoding; /* audio encoding -- ulaw/linear */ + u_int sc_encoding; /* audio encoding -- ulaw/linear */ int sc_chans; /* # of channels */ int sc_precision; /* # bits per sample */ @@ -165,9 +165,8 @@ void aria_prometheus_kludge __P((struct isa_attach_args *)); int aria_set_sr __P((void *, u_long)); u_long aria_get_sr __P((void *)); int aria_query_encoding __P((void *, struct audio_encoding *)); -int aria_set_encoding __P((void *, u_int)); +int aria_set_format __P((void *, u_int, u_int)); int aria_get_encoding __P((void *)); -int aria_set_precision __P((void *, u_int)); int aria_get_precision __P((void *)); int aria_set_channels __P((void *, int)); int aria_get_channels __P((void *)); @@ -186,8 +185,6 @@ int aria_halt_input __P((void *)); int aria_halt_output __P((void *)); int aria_cont __P((void *)); -u_int aria_get_silence __P((int)); - int aria_sendcmd __P((u_short, u_short, int, int, int)); u_short aria_getdspmem __P((u_short, u_short)); @@ -236,9 +233,8 @@ struct audio_hw_if aria_hw_if = { aria_set_sr, aria_get_sr, aria_query_encoding, - aria_set_encoding, + aria_set_format, aria_get_encoding, - aria_set_precision, aria_get_precision, aria_set_channels, aria_get_channels, @@ -248,7 +244,6 @@ struct audio_hw_if aria_hw_if = { aria_set_in_port, aria_get_in_port, aria_commit_settings, - aria_get_silence, mulaw_expand, mulaw_compress, aria_start_output, @@ -613,24 +608,31 @@ aria_query_encoding(addr, fp) } int -aria_set_encoding(addr, enc) +aria_set_format(addr, enc, precision) void *addr; - u_int enc; + u_int enc, prec; { register struct aria_softc *sc = addr; - DPRINTF(("aria_set_encoding\n")); + DPRINTF(("aria_set_format\n")); switch(enc){ case AUDIO_ENCODING_ULAW: - sc->encoding = AUDIO_ENCODING_ULAW; - break; - case AUDIO_ENCODING_LINEAR: - sc->encoding = AUDIO_ENCODING_LINEAR; - break; + case AUDIO_ENCODING_PCM16: + case AUDIO_ENCODING_PCM8: + break; default: return (EINVAL); } + + if (prec!=8 && prec!=16) + return (EINVAL); + + if (sc->encoding!=AUDIO_ENCODING_PCM16 && prec==16) + return (EINVAL); + + sc->sc_encoding = enc; + sc->sc_precision = prec; return (0); } @@ -646,25 +648,6 @@ aria_get_encoding(addr) } int -aria_set_precision(addr, prec) - void *addr; - u_int prec; -{ - struct aria_softc *sc = addr; - - DPRINTF(("aria_set_precision\n")); - - if (prec!=8 && prec!=16) - return EINVAL; - - if (sc->encoding!=AUDIO_ENCODING_PCM16 && prec==16) - return EINVAL; - - sc->sc_precision = prec; - return(0); -} - -int aria_get_precision(addr) void *addr; { @@ -1217,32 +1200,6 @@ aria_intr(arg) return 1; } -u_int -aria_get_silence(enc) - int enc; -{ -#define ULAW_SILENCE 0x7f -#define ALAW_SILENCE 0x55 -#define LINEAR_SILENCE 0x00 - u_int auzero; - - switch (enc) { - case AUDIO_ENCODING_ULAW: - auzero = ULAW_SILENCE; - break; - case AUDIO_ENCODING_ALAW: - auzero = ALAW_SILENCE; - break; - case AUDIO_ENCODING_PCM8: - case AUDIO_ENCODING_PCM16: - default: - auzero = LINEAR_SILENCE; - break; - } - - return(auzero); -} - int aria_setfd(addr, flag) void *addr; diff --git a/sys/dev/isa/files.isa b/sys/dev/isa/files.isa index 0d1005f2c92..dcf73b35c43 100644 --- a/sys/dev/isa/files.isa +++ b/sys/dev/isa/files.isa @@ -1,4 +1,4 @@ -# $OpenBSD: files.isa,v 1.32 1996/12/12 09:17:30 mickey Exp $ +# $OpenBSD: files.isa,v 1.33 1997/07/10 23:06:33 provos Exp $ # $NetBSD: files.isa,v 1.21 1996/05/16 03:45:55 mycroft Exp $ # # Config.new file and device description for machine-independent ISA code. @@ -215,9 +215,11 @@ file dev/isa/sbdsp.c sbdsp # SoundBlaster family device sb: audio, isa_dma, sbdsp, mulaw, opti -attach sb at isa file dev/isa/sb.c sb needs-flag +attach sb at isa with sb_isa +file dev/isa/sb_isa.c sb_isa needs-flag + # Soundcards based on Sierra's Aria chipset. # Such as the Prometheus Aria 16 or the Diamond # sonic sound. diff --git a/sys/dev/isa/gus.c b/sys/dev/isa/gus.c index f87d3928e19..85d140414cd 100644 --- a/sys/dev/isa/gus.c +++ b/sys/dev/isa/gus.c @@ -1,4 +1,4 @@ -/* $OpenBSD: gus.c,v 1.11 1996/05/26 00:27:15 deraadt Exp $ */ +/* $OpenBSD: gus.c,v 1.12 1997/07/10 23:06:34 provos Exp $ */ /* $NetBSD: gus.c,v 1.16 1996/05/12 23:52:08 mycroft Exp $ */ /*- @@ -364,13 +364,11 @@ int gus_set_out_sr __P((void *, u_long)); u_long gus_get_out_sr __P((void *)); int gusmax_set_out_sr __P((void *, u_long)); u_long gusmax_get_out_sr __P((void *)); -int gus_set_encoding __P((void *, u_int)); +int gus_set_format __P((void *, u_int, u_int)); int gus_get_encoding __P((void *)); -int gusmax_set_encoding __P((void *, u_int)); -int gusmax_get_encoding __P((void *)); -int gus_set_precision __P((void *, u_int)); int gus_get_precision __P((void *)); -int gusmax_set_precision __P((void *, u_int)); +int gusmax_set_format __P((void *, u_int, u_int)); +int gusmax_get_encoding __P((void *)); int gusmax_get_precision __P((void *)); int gus_set_channels __P((void *, int)); int gus_get_channels __P((void *)); @@ -389,8 +387,6 @@ int gus_halt_in_dma __P((void *)); int gus_cont_out_dma __P((void *)); int gus_cont_in_dma __P((void *)); int gus_speaker_ctl __P((void *, int)); -int gusmax_set_precision __P((void *, u_int)); -int gusmax_get_precision __P((void *)); int gusmax_round_blocksize __P((void *, int)); int gusmax_commit_settings __P((void *)); int gusmax_dma_output __P((void *, void *, int, void (*)(void *), void *)); @@ -624,10 +620,8 @@ struct audio_hw_if gus_hw_if = { gus_get_out_sr, gus_query_encoding, - gus_set_encoding, + gus_set_format, gus_get_encoding, - - gus_set_precision, gus_get_precision, gus_set_channels, @@ -642,8 +636,6 @@ struct audio_hw_if gus_hw_if = { gus_commit_settings, - ad1848_get_silence, - gus_expand, mulaw_compress, @@ -2123,43 +2115,52 @@ gus_set_volume(sc, voice, volume) */ int -gusmax_set_encoding(addr, encoding) +gusmax_set_format(addr, encoding, precision) void * addr; - u_int encoding; + u_int encoding, precision; { register struct ad1848_softc *ac = addr; register struct gus_softc *sc = ac->parent; - (void) ad1848_set_encoding(ac, encoding); - return gus_set_encoding(sc, encoding); + int error; + + error = ad1848_set_format(ac, encoding, precision); + return (error ? error : gus_set_format(sc, encoding, precision)); } int -gus_set_encoding(addr, encoding) +gus_set_format(addr, encoding, precision) void * addr; - u_int encoding; + u_int encoding, precision; { register struct gus_softc *sc = addr; + int s; - DPRINTF(("gus_set_encoding called\n")); - - /* XXX todo: add alaw for codec */ - if (encoding != AUDIO_ENCODING_ULAW && - encoding != AUDIO_ENCODING_PCM16 && - encoding != AUDIO_ENCODING_PCM8) - return EINVAL; + DPRINTF(("gus_set_format called\n")); - if (encoding != AUDIO_ENCODING_PCM16) - sc->sc_precision = 8; /* XXX force it. */ + switch (encoding) { + case AUDIO_ENCODING_ULAW: + case AUDIO_ENCODING_PCM16: + case AUDIO_ENCODING_PCM8: + break; + default: + return (EINVAL); + } - sc->sc_encoding = encoding; + s = splaudio(); - if (sc->sc_precision == 8) { + if (precision == 8) { sc->sc_voc[GUS_VOICE_LEFT].voccntl &= ~GUSMASK_DATA_SIZE16; sc->sc_voc[GUS_VOICE_RIGHT].voccntl &= ~GUSMASK_DATA_SIZE16; } else { sc->sc_voc[GUS_VOICE_LEFT].voccntl |= GUSMASK_DATA_SIZE16; sc->sc_voc[GUS_VOICE_RIGHT].voccntl |= GUSMASK_DATA_SIZE16; } + + sc->sc_encoding = encoding; + sc->sc_precision = precision; + + splx(s); + return 0; } @@ -2170,8 +2171,10 @@ gusmax_set_channels(addr, channels) { register struct ad1848_softc *ac = addr; register struct gus_softc *sc = ac->parent; - (void) ad1848_set_channels(ac, channels); - return gus_set_channels(sc, channels); + int error; + + error = ad1848_set_channels(ac, channels); + return (error ? error : gus_set_channels(sc, channels)); } int @@ -2192,51 +2195,6 @@ gus_set_channels(addr, channels) } /* - * Interface to the audio layer - set the data precision - */ - -int -gusmax_set_precision(addr, bits) - void * addr; - u_int bits; -{ - register struct ad1848_softc *ac = addr; - register struct gus_softc *sc = ac->parent; - - (void) ad1848_set_precision(ac, bits); - return gus_set_precision(sc, bits); -} - - -int -gus_set_precision(addr, bits) - void * addr; - u_int bits; -{ - register struct gus_softc *sc = addr; - - DPRINTF(("gus_set_precision called\n")); - - if (bits != 8 && bits != 16) - return EINVAL; - - if (sc->sc_encoding != AUDIO_ENCODING_PCM16 && bits != 8) - /* If we're doing PCM8 or MULAW, it must be 8 bits. */ - return EINVAL; - - sc->sc_precision = bits; - - if (bits == 16) { - sc->sc_voc[GUS_VOICE_LEFT].voccntl |= GUSMASK_DATA_SIZE16; - sc->sc_voc[GUS_VOICE_RIGHT].voccntl |= GUSMASK_DATA_SIZE16; - } else { - sc->sc_voc[GUS_VOICE_LEFT].voccntl &= ~GUSMASK_DATA_SIZE16; - sc->sc_voc[GUS_VOICE_RIGHT].voccntl &= ~GUSMASK_DATA_SIZE16; - } - return 0; -} - -/* * Interface to the audio layer - set the blocksize to the correct number * of units */ @@ -2412,8 +2370,10 @@ gusmax_set_out_sr(addr, rate) { register struct ad1848_softc *ac = addr; register struct gus_softc *sc = ac->parent; - (void) ad1848_set_out_sr(ac, rate); - return gus_set_out_sr(sc, rate); + int error; + + error = ad1848_set_out_sr(ac, rate); + return (error ? error : gus_set_out_sr(sc, rate)); } int @@ -2571,8 +2531,10 @@ gusmax_set_in_sr(addr, rate) { register struct ad1848_softc *ac = addr; register struct gus_softc *sc = ac->parent; - (void) ad1848_set_in_sr(ac, rate); - return gus_set_in_sr(sc, rate); + int error; + + error = ad1848_set_in_sr(ac, rate); + return (error ? error : gus_set_in_sr(sc, rate)); } @@ -3007,10 +2969,8 @@ gus_init_cs4231(sc) gusmax_get_out_sr, ad1848_query_encoding, /* query encoding */ - gusmax_set_encoding, + gusmax_set_format, gusmax_get_encoding, - - gusmax_set_precision, gusmax_get_precision, gusmax_set_channels, @@ -3025,8 +2985,6 @@ gus_init_cs4231(sc) gusmax_commit_settings, - ad1848_get_silence, - gusmax_expand, /* XXX use codec */ mulaw_compress, diff --git a/sys/dev/isa/gusreg.h b/sys/dev/isa/gusreg.h index 975ba6ec74e..88f55d1cf81 100644 --- a/sys/dev/isa/gusreg.h +++ b/sys/dev/isa/gusreg.h @@ -1,4 +1,4 @@ -/* $OpenBSD: gusreg.h,v 1.2 1996/03/08 16:42:56 niklas Exp $ */ +/* $OpenBSD: gusreg.h,v 1.3 1997/07/10 23:06:35 provos Exp $ */ /* $NetBSD: gusreg.h,v 1.3 1996/02/05 02:22:10 jtc Exp $ */ /*- @@ -243,17 +243,16 @@ * Codec/Mixer registers */ -/* all these get +4 more in ad1848, sigh. */ -#define GUS_MAX_CODEC_BASE 0x108 -#define GUS_DAUGHTER_CODEC_BASE 0x52C -#define GUS_DAUGHTER_CODEC_BASE2 0x600 -#define GUS_DAUGHTER_CODEC_BASE3 0xE7C -#define GUS_DAUGHTER_CODEC_BASE4 0xF3C - -#define GUS_CODEC_SELECT 4 /* base + 0 */ -#define GUS_CODEC_DATA 5 /* base + 1 */ -#define GUS_CODEC_STATUS 6 /* base + 2 */ -#define GUS_CODEC_PIO 7 /* base + 3 */ +#define GUS_MAX_CODEC_BASE 0x10C +#define GUS_DAUGHTER_CODEC_BASE 0x530 +#define GUS_DAUGHTER_CODEC_BASE2 0x604 +#define GUS_DAUGHTER_CODEC_BASE3 0xE80 +#define GUS_DAUGHTER_CODEC_BASE4 0xF40 + +#define GUS_CODEC_SELECT 0 +#define GUS_CODEC_DATA 1 +#define GUS_CODEC_STATUS 2 +#define GUS_CODEC_PIO 3 #define GUS_MAX_CTRL 0x106 #define GUS_MAX_BASEBITS 0xf /* sets middle nibble of 3X6 */ diff --git a/sys/dev/isa/pas.c b/sys/dev/isa/pas.c index 98a323be306..41236ebe549 100644 --- a/sys/dev/isa/pas.c +++ b/sys/dev/isa/pas.c @@ -1,4 +1,4 @@ -/* $OpenBSD: pas.c,v 1.13 1996/10/16 12:33:39 deraadt Exp $ */ +/* $OpenBSD: pas.c,v 1.14 1997/07/10 23:06:36 provos Exp $ */ /* $NetBSD: pas.c,v 1.17 1996/05/12 23:53:18 mycroft Exp $ */ /* @@ -113,9 +113,8 @@ struct audio_hw_if pas_hw_if = { sbdsp_set_out_sr, sbdsp_get_out_sr, sbdsp_query_encoding, - sbdsp_set_encoding, + sbdsp_set_format, sbdsp_get_encoding, - sbdsp_set_precision, sbdsp_get_precision, sbdsp_set_channels, sbdsp_get_channels, @@ -125,7 +124,6 @@ struct audio_hw_if pas_hw_if = { sbdsp_set_in_port, sbdsp_get_in_port, sbdsp_commit_settings, - sbdsp_get_silence, mulaw_expand, mulaw_compress, sbdsp_dma_output, @@ -345,8 +343,6 @@ pasprobe(parent, match, aux) } /* Now a SoundBlaster */ -/* sc->sc_iobase = ia->ia_iobase; */ - /* and set the SB iobase into the DSP as well ... */ sc->sc_sbdsp.sc_iobase = ia->ia_iobase; if (sbdsp_reset(&sc->sc_sbdsp) < 0) { DPRINTF(("pas: couldn't reset card\n")); @@ -379,7 +375,8 @@ pasprobe(parent, match, aux) } sc->sc_sbdsp.sc_irq = ia->ia_irq; - sc->sc_sbdsp.sc_drq = ia->ia_drq; + sc->sc_sbdsp.sc_drq8 = ia->ia_drq; + sc->sc_sbdsp.sc_drq16 = -1; /* XXX */ if (sbdsp_probe(&sc->sc_sbdsp) == 0) { DPRINTF(("pas: sbdsp probe failed\n")); diff --git a/sys/dev/isa/pss.c b/sys/dev/isa/pss.c index 3c7e94ef2c7..651a644c097 100644 --- a/sys/dev/isa/pss.c +++ b/sys/dev/isa/pss.c @@ -1,4 +1,4 @@ -/* $OpenBSD: pss.c,v 1.10 1996/05/26 00:27:27 deraadt Exp $ */ +/* $OpenBSD: pss.c,v 1.11 1997/07/10 23:06:36 provos Exp $ */ /* $NetBSD: pss.c,v 1.15 1996/05/12 23:53:23 mycroft Exp $ */ /* @@ -74,6 +74,9 @@ #include <dev/isa/wssreg.h> #include <dev/isa/pssreg.h> +/* XXX Default WSS base */ +#define WSS_BASE_ADDRESS 0x0530 + /* * Mixer devices */ @@ -106,7 +109,9 @@ struct pss_softc { struct device sc_dev; /* base device */ +#ifdef NEWCONFIG struct isadev sc_id; /* ISA device */ +#endif void *sc_ih; /* interrupt vectoring */ int sc_iobase; /* I/O port base address */ @@ -125,23 +130,29 @@ struct pss_softc { int mic_mute, cd_mute, dac_mute; }; +#ifdef notyet struct mpu_softc { struct device sc_dev; /* base device */ +#ifdef NEWCONFIG struct isadev sc_id; /* ISA device */ +#endif void *sc_ih; /* interrupt vectoring */ int sc_iobase; /* MIDI I/O port base address */ int sc_irq; /* MIDI interrupt */ }; -struct cd_softc { +struct pcd_softc { struct device sc_dev; /* base device */ +#ifdef NEWCONFIG struct isadev sc_id; /* ISA device */ +#endif void *sc_ih; /* interrupt vectoring */ int sc_iobase; /* CD I/O port base address */ int sc_irq; /* CD interrupt */ }; +#endif #ifdef AUDIO_DEBUG extern void Dprintf __P((const char *, ...)); @@ -157,16 +168,20 @@ void pssattach __P((struct device *, struct device *, void *)); int spprobe __P((struct device *, void *, void *)); void spattach __P((struct device *, struct device *, void *)); +#ifdef notyet int mpuprobe __P((struct device *, void *, void *)); void mpuattach __P((struct device *, struct device *, void *)); int pcdprobe __P((struct device *, void *, void *)); void pcdattach __P((struct device *, struct device *, void *)); +#endif int spopen __P((dev_t, int)); int pssintr __P((void *)); +#ifdef notyet int mpuintr __P((void *)); +#endif int pss_speaker_ctl __P((void *, int)); @@ -181,14 +196,21 @@ int pss_mixer_set_port __P((void *, mixer_ctrl_t *)); int pss_mixer_get_port __P((void *, mixer_ctrl_t *)); int pss_query_devinfo __P((void *, mixer_devinfo_t *)); +#ifdef PSS_DSP void pss_dspwrite __P((struct pss_softc *, int)); +#endif void pss_setaddr __P((int, int)); int pss_setint __P((int, int)); int pss_setdma __P((int, int)); +int pss_testirq __P((struct pss_softc *, int)); int pss_testdma __P((struct pss_softc *, int)); +#ifdef notyet int pss_reset_dsp __P((struct pss_softc *)); int pss_download_dsp __P((struct pss_softc *, u_char *, int)); +#endif +#ifdef AUDIO_DEBUG void pss_dump_regs __P((struct pss_softc *)); +#endif int pss_set_master_gain __P((struct pss_softc *, struct ad1848_volume *)); int pss_set_master_mode __P((struct pss_softc *, int)); int pss_set_treble __P((struct pss_softc *, u_int)); @@ -201,7 +223,9 @@ int pss_get_bass __P((struct pss_softc *, u_char *)); static int pss_to_vol __P((mixer_ctrl_t *, struct ad1848_volume *)); static int pss_from_vol __P((mixer_ctrl_t *, struct ad1848_volume *)); +#ifdef AUDIO_DEBUG void wss_dump_regs __P((struct ad1848_softc *)); +#endif /* * Define our interface to the higher level audio driver. @@ -216,9 +240,8 @@ struct audio_hw_if pss_audio_if = { ad1848_set_out_sr, ad1848_get_out_sr, ad1848_query_encoding, - ad1848_set_encoding, + ad1848_set_format, ad1848_get_encoding, - ad1848_set_precision, ad1848_get_precision, ad1848_set_channels, ad1848_get_channels, @@ -228,7 +251,6 @@ struct audio_hw_if pss_audio_if = { pss_set_in_port, pss_get_in_port, ad1848_commit_settings, - ad1848_get_silence, NULL, NULL, ad1848_dma_output, @@ -249,18 +271,15 @@ struct audio_hw_if pss_audio_if = { /* Interrupt translation for WSS config */ -static u_char wss_interrupt_bits[12] = { +static u_char wss_interrupt_bits[16] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x08, - 0xff, 0x10, 0x18, 0x20 + 0xff, 0x10, 0x18, 0x20, + 0xff, 0xff, 0xff, 0xff }; /* ditto for WSS DMA channel */ static u_char wss_dma_bits[4] = {1, 2, 0, 3}; -#ifndef NEWCONFIG -#define at_dma(flags, ptr, cc, chan) isa_dmastart(flags, ptr, cc, chan) -#endif - struct cfattach pss_ca = { sizeof(struct pss_softc), pssprobe, pssattach }; @@ -277,6 +296,7 @@ struct cfdriver sp_cd = { NULL, "sp", DV_DULL }; +#ifdef notyet struct cfattach mpu_ca = { sizeof(struct mpu_softc), mpuprobe, mpuattach }; @@ -286,12 +306,13 @@ struct cfdriver mpu_cd = { }; struct cfattach pcd_ca = { - sizeof(struct cd_softc), pcdprobe, pcdattach + sizeof(struct pcd_softc), pcdprobe, pcdattach }; struct cfdriver pcd_cd = { NULL, "pcd", DV_DULL }; +#endif struct audio_device pss_device = { "pss,ad1848", @@ -299,6 +320,7 @@ struct audio_device pss_device = { "PSS" }; +#ifdef PSS_DSP void pss_dspwrite(sc, data) struct pss_softc *sc; @@ -322,6 +344,7 @@ pss_dspwrite(sc, data) } printf ("pss: DSP Command (%04x) Timeout.\n", data); } +#endif /* PSS_DSP */ void pss_setaddr(addr, configAddr) @@ -347,58 +370,48 @@ pss_setint(intNum, configAddress) int configAddress; { int val; + switch(intNum) { - case 0: - val = inw(configAddress); - val &= INT_MASK; - outw(configAddress,val); - break; case 3: val = inw(configAddress); val &= INT_MASK; val |= INT_3_BITS; - outw(configAddress,val); break; case 5: val = inw(configAddress); val &= INT_MASK; val |= INT_5_BITS; - outw(configAddress,val); break; case 7: val = inw(configAddress); val &= INT_MASK; val |= INT_7_BITS; - outw(configAddress,val); break; case 9: val = inw(configAddress); val &= INT_MASK; val |= INT_9_BITS; - outw(configAddress,val); break; case 10: val = inw(configAddress); val &= INT_MASK; val |= INT_10_BITS; - outw(configAddress,val); break; case 11: val = inw(configAddress); val &= INT_MASK; val |= INT_11_BITS; - outw(configAddress,val); break; case 12: val = inw(configAddress); val &= INT_MASK; val |= INT_12_BITS; - outw(configAddress,val); break; default: - printf("pss_setint unkown int\n"); + DPRINTF(("pss_setint: invalid irq (%d)\n", intNum)); return 1; } + outw(configAddress,val); return 0; } @@ -414,55 +427,50 @@ pss_setdma(dmaNum, configAddress) val = inw(configAddress); val &= DMA_MASK; val |= DMA_0_BITS; - outw(configAddress,val); break; case 1: val = inw(configAddress); val &= DMA_MASK; val |= DMA_1_BITS; - outw(configAddress,val); break; case 3: val = inw(configAddress); val &= DMA_MASK; val |= DMA_3_BITS; - outw(configAddress,val); break; case 5: val = inw(configAddress); val &= DMA_MASK; val |= DMA_5_BITS; - outw(configAddress,val); break; case 6: val = inw(configAddress); val &= DMA_MASK; val |= DMA_6_BITS; - outw(configAddress,val); break; case 7: val = inw(configAddress); val &= DMA_MASK; val |= DMA_7_BITS; - outw(configAddress,val); break; default: - printf("PSS ERROR! pss_setdma: unknown_dma\n"); + DPRINTF(("pss_setdma: invalid drq (%d)\n", dmaNum)); return 1; } + outw(configAddress, val); return 0; } /* * This function tests an interrupt number to see if - * it is availible. It takes the interrupt button - * as it's argument and returns TRUE if the interrupt + * it is available. It takes the interrupt button + * as its argument and returns TRUE if the interrupt * is ok. */ -static int +int pss_testirq(struct pss_softc *sc, int intNum) { - int iobase = sc->sc_iobase; + int config = sc->sc_iobase + PSS_CONFIG; int val; int ret; int i; @@ -470,61 +478,50 @@ pss_testirq(struct pss_softc *sc, int intNum) /* Set the interrupt bits */ switch(intNum) { case 3: - val = inw(iobase+PSS_CONFIG); + val = inw(config); val &= INT_MASK; /* Special: 0 */ - outw(iobase+PSS_CONFIG, val); break; case 5: - val = inw(iobase+PSS_CONFIG); + val = inw(config); val &= INT_MASK; - val |= INT_5_BITS; - outw(iobase+PSS_CONFIG,val); + val |= INT_TEST_BIT | INT_5_BITS; break; case 7: - val = inw(iobase+PSS_CONFIG); + val = inw(config); val &= INT_MASK; - val |= INT_7_BITS; - outw(iobase+PSS_CONFIG,val); + val |= INT_TEST_BIT | INT_7_BITS; break; case 9: - val = inw(iobase+PSS_CONFIG); + val = inw(config); val &= INT_MASK; - val |= INT_9_BITS; - outw(iobase+PSS_CONFIG,val); + val |= INT_TEST_BIT | INT_9_BITS; break; case 10: - val = inw(iobase+PSS_CONFIG); + val = inw(config); val &= INT_MASK; - val |= INT_10_BITS; - outw(iobase+PSS_CONFIG,val); + val |= INT_TEST_BIT | INT_10_BITS; break; case 11: - val = inw(iobase+PSS_CONFIG); + val = inw(config); val &= INT_MASK; - val |= INT_11_BITS; - outw(iobase+PSS_CONFIG,val); + val |= INT_TEST_BIT | INT_11_BITS; break; case 12: - val = inw(iobase+PSS_CONFIG); + val = inw(config); val &= INT_MASK; - val |= INT_12_BITS; - outw(iobase+PSS_CONFIG,val); + val |= INT_TEST_BIT | INT_12_BITS; break; default: - DPRINTF(("pss: unknown IRQ (%d)\n", intNum)); + DPRINTF(("pss_testirq: invalid irq (%d)\n", intNum)); return 0; } - - /* Set the interrupt test bit */ - val = inw(iobase+PSS_CONFIG); - val |= INT_TEST_BIT; - outw(iobase+PSS_CONFIG,val); + outw(config, val); /* Check if the interrupt is in use */ /* Do it a few times in case there is a delay */ ret = 0; for (i = 0; i < 5; i++) { - val = inw(iobase+PSS_CONFIG); + val = inw(config); if (val & INT_TEST_PASS) { ret = 1; break; @@ -532,17 +529,16 @@ pss_testirq(struct pss_softc *sc, int intNum) } /* Clear the Test bit and the interrupt bits */ - val = inw(iobase+PSS_CONFIG); - val &= INT_TEST_BIT_MASK; - val &= INT_MASK; - outw(iobase+PSS_CONFIG,val); + val = inw(config); + val &= INT_TEST_BIT_MASK & INT_MASK; + outw(config, val); return(ret); } /* * This function tests a dma channel to see if - * it is availible. It takes the DMA channel button - * as it's argument and returns TRUE if the channel + * it is available. It takes the DMA channel button + * as its argument and returns TRUE if the channel * is ok. */ int @@ -550,62 +546,52 @@ pss_testdma(sc, dmaNum) struct pss_softc *sc; int dmaNum; { - int iobase = sc->sc_iobase; + int config = sc->sc_iobase + PSS_CONFIG; int val; - int i,ret; + int i, ret; switch (dmaNum) { case 0: - val = inw(iobase+PSS_CONFIG); + val = inw(config); val &= DMA_MASK; - val |= DMA_0_BITS; - outw(iobase+PSS_CONFIG,val); + val |= DMA_TEST_BIT | DMA_0_BITS; break; case 1: - val = inw(iobase+PSS_CONFIG); + val = inw(config); val &= DMA_MASK; - val |= DMA_1_BITS; - outw(iobase+PSS_CONFIG,val); + val |= DMA_TEST_BIT | DMA_1_BITS; break; case 3: - val = inw(iobase+PSS_CONFIG); + val = inw(config); val &= DMA_MASK; - val |= DMA_3_BITS; - outw(iobase+PSS_CONFIG,val); + val |= DMA_TEST_BIT | DMA_3_BITS; break; case 5: - val = inw(iobase+PSS_CONFIG); + val = inw(config); val &= DMA_MASK; - val |= DMA_5_BITS; - outw(iobase+PSS_CONFIG,val); + val |= DMA_TEST_BIT | DMA_5_BITS; break; case 6: - val = inw(iobase+PSS_CONFIG); + val = inw(config); val &= DMA_MASK; - val |= DMA_6_BITS; - outw(iobase+PSS_CONFIG,val); + val |= DMA_TEST_BIT | DMA_6_BITS; break; case 7: - val = inw(iobase+PSS_CONFIG); + val = inw(config); val &= DMA_MASK; - val |= DMA_7_BITS; - outw(iobase+PSS_CONFIG,val); + val |= DMA_TEST_BIT | DMA_7_BITS; break; default: - DPRINTF(("pss: unknown DMA channel (%d)\n", dmaNum)); + DPRINTF(("pss_testdma: invalid drq (%d)\n", dmaNum)); return 0; } - - /* Set the DMA test bit */ - val = inw(iobase+PSS_CONFIG); - val |= DMA_TEST_BIT; - outw(iobase+PSS_CONFIG,val); + outw(config, val); /* Check if the DMA channel is in use */ /* Do it a few times in case there is a delay */ ret = 0; for (i = 0; i < 3; i++) { - val = inw(iobase+PSS_CONFIG); + val = inw(config); if (val & DMA_TEST_PASS) { ret = 1; break; @@ -613,13 +599,13 @@ pss_testdma(sc, dmaNum) } /* Clear the Test bit and the DMA bits */ - val = inw(iobase+PSS_CONFIG); - val &= DMA_TEST_BIT_MASK; - val &= DMA_MASK; - outw(iobase+PSS_CONFIG,val); + val = inw(config); + val &= DMA_TEST_BIT_MASK & DMA_MASK; + outw(config, val); return(ret); } +#ifdef notyet int pss_reset_dsp(sc) struct pss_softc *sc; @@ -639,8 +625,8 @@ pss_reset_dsp(sc) /* * This function loads an image into the PSS - * card. The function loads the file by putting - * reseting the dsp and feeding it the boot bytes. + * card. The function loads the file by + * resetting the dsp and feeding it the boot bytes. * First you feed the ASIC the first byte of * the boot sequence. The ASIC waits until it * detects a BMS and RD and asserts BR @@ -720,28 +706,32 @@ pss_download_dsp(sc, block, size) return 1; } +#endif /* notyet */ +#ifdef AUDIO_DEBUG void wss_dump_regs(sc) struct ad1848_softc *sc; { - printf("WSS regs: config=%x version=%x\n", - (u_char)inb(sc->sc_iobase+WSS_CONFIG), - (u_char)inb(sc->sc_iobase+WSS_STATUS)); + + printf("WSS reg: status=%02x\n", + (u_char)inb(sc->sc_iobase-WSS_CODEC+WSS_STATUS)); } void pss_dump_regs(sc) struct pss_softc *sc; { - printf("PSS regs: status=%x vers=%x ", + + printf("PSS regs: status=%04x vers=%04x ", (u_short)inw(sc->sc_iobase+PSS_STATUS), (u_short)inw(sc->sc_iobase+PSS_ID_VERS)); - printf("config=%x wss_config=%x\n", + printf("config=%04x wss_config=%04x\n", (u_short)inw(sc->sc_iobase+PSS_CONFIG), (u_short)inw(sc->sc_iobase+PSS_WSS_CONFIG)); } +#endif /* * Probe for the PSS hardware. @@ -784,7 +774,7 @@ pss_found: sc->sc_iobase = iobase; /* Clear WSS config */ - pss_setaddr(WSS_BASE_ADDRESS, sc->sc_iobase+PSS_WSS_CONFIG); + pss_setaddr(WSS_BASE_ADDRESS, sc->sc_iobase+PSS_WSS_CONFIG); /* XXX! */ outb(WSS_BASE_ADDRESS+WSS_CONFIG, 0); /* Clear config registers (POR reset state) */ @@ -828,7 +818,7 @@ pss_found: pss_setint(ia->ia_irq, sc->sc_iobase+PSS_CONFIG); pss_setdma(sc->sc_drq, sc->sc_iobase+PSS_CONFIG); - +#ifdef notyet /* Setup the Game port */ #ifdef PSS_GAMEPORT DPRINTF(("Turning Game Port On.\n")); @@ -839,6 +829,7 @@ pss_found: /* Reset DSP */ pss_reset_dsp(sc); +#endif /* notyet */ return 1; } @@ -857,10 +848,10 @@ spprobe(parent, match, aux) u_char bits; int i; - sc->sc_iobase = cf->cf_iobase; + sc->sc_iobase = cf->cf_iobase + WSS_CODEC; /* Set WSS io address */ - pss_setaddr(sc->sc_iobase, pc->sc_iobase+PSS_WSS_CONFIG); + pss_setaddr(cf->cf_iobase, pc->sc_iobase+PSS_WSS_CONFIG); /* Is there an ad1848 chip at the WSS iobase ? */ if (ad1848_probe(sc) == 0) { @@ -940,6 +931,7 @@ spprobe(parent, match, aux) return 1; } +#ifdef notyet int mpuprobe(parent, match, aux) struct device *parent; @@ -990,7 +982,7 @@ pcdprobe(parent, match, aux) struct device *parent; void *match, *aux; { - struct cd_softc *sc = match; + struct pcd_softc *sc = match; struct pss_softc *pc = (void *) parent; struct cfdata *cf = (void *)sc->sc_dev.dv_cfdata; u_short val; @@ -1035,6 +1027,7 @@ pcdprobe(parent, match, aux) return 1; } +#endif /* notyet */ /* * Attach hardware to driver, attach hardware driver to audio @@ -1097,7 +1090,7 @@ spattach(parent, self, aux) #endif sc->sc_ih = isa_intr_establish(ic, cf->cf_irq, IST_EDGE, IPL_AUDIO, - ad1848_intr, sc, sc->sc_dev.dv_xname); + ad1848_intr, sc); /* XXX might use pssprint func ?? */ printf(" port 0x%x-0x%x irq %d drq %d", @@ -1109,6 +1102,7 @@ spattach(parent, self, aux) printf("\n"); } +#ifdef notyet void mpuattach(parent, self, aux) struct device *parent, *self; @@ -1126,7 +1120,7 @@ mpuattach(parent, self, aux) #endif sc->sc_ih = isa_intr_establish(ic, cf->cf_irq, IST_EDGE, IPL_AUDIO, - mpuintr, sc, sc->sc_dev.dv_xname); + mpuintr, sc); /* XXX might use pssprint func ?? */ printf(" port 0x%x-0x%x irq %d\n", @@ -1139,7 +1133,7 @@ pcdattach(parent, self, aux) struct device *parent, *self; void *aux; { - struct cd_softc *sc = (struct cd_softc *)self; + struct pcd_softc *sc = (struct pcd_softc *)self; struct cfdata *cf = (void *)sc->sc_dev.dv_cfdata; int iobase = cf->cf_iobase; @@ -1159,6 +1153,7 @@ pcdattach(parent, self, aux) sc->sc_iobase, sc->sc_iobase+2, cf->cf_irq); } +#endif /* notyet */ static int pss_to_vol(cp, vol) @@ -1378,6 +1373,7 @@ pssintr(arg) return 0; } +#ifdef notyet int mpuintr(arg) void *arg; @@ -1392,6 +1388,7 @@ mpuintr(arg) /* XXX Need to clear intr */ return 1; } +#endif int pss_getdev(addr, retp) diff --git a/sys/dev/isa/sb.c b/sys/dev/isa/sb.c index 495009c13f5..09f09d4f5bb 100644 --- a/sys/dev/isa/sb.c +++ b/sys/dev/isa/sb.c @@ -1,4 +1,4 @@ -/* $OpenBSD: sb.c,v 1.11 1996/05/26 00:27:28 deraadt Exp $ */ +/* $OpenBSD: sb.c,v 1.12 1997/07/10 23:06:37 provos Exp $ */ /* $NetBSD: sb.c,v 1.36 1996/05/12 23:53:33 mycroft Exp $ */ /* @@ -54,16 +54,9 @@ #include <dev/isa/isavar.h> #include <dev/isa/isadmavar.h> -#include <dev/isa/sbdspvar.h> #include <dev/isa/sbreg.h> - -#ifdef AUDIO_DEBUG -extern void Dprintf __P((const char *, ...)); -#define DPRINTF(x) if (sbdebug) Dprintf x -int sbdebug = 0; -#else -#define DPRINTF(x) -#endif +#include <dev/isa/sbvar.h> +#include <dev/isa/sbdspvar.h> struct sb_softc { struct device sc_dev; /* base device */ @@ -73,13 +66,6 @@ struct sb_softc { struct sbdsp_softc sc_sbdsp; }; -int sbprobe __P((struct device *, void *, void *)); -void sbattach __P((struct device *, struct device *, void *)); - -struct cfattach sb_ca = { - sizeof(struct sbdsp_softc), sbprobe, sbattach -}; - struct cfdriver sb_cd = { NULL, "sb", DV_DULL }; @@ -106,9 +92,8 @@ struct audio_hw_if sb_hw_if = { sbdsp_set_out_sr, sbdsp_get_out_sr, sbdsp_query_encoding, - sbdsp_set_encoding, + sbdsp_set_format, sbdsp_get_encoding, - sbdsp_set_precision, sbdsp_get_precision, sbdsp_set_channels, sbdsp_get_channels, @@ -118,7 +103,6 @@ struct audio_hw_if sb_hw_if = { sbdsp_set_in_port, sbdsp_get_in_port, sbdsp_commit_settings, - sbdsp_get_silence, mulaw_expand, mulaw_compress, sbdsp_dma_output, @@ -141,106 +125,144 @@ struct audio_hw_if sb_hw_if = { * Probe / attach routines. */ -/* - * Probe for the soundblaster hardware. - */ + int -sbprobe(parent, match, aux) - struct device *parent; - void *match, *aux; +sbmatch(sc) + struct sbdsp_softc *sc; { - register struct sbdsp_softc *sc = match; - register struct isa_attach_args *ia = aux; - register int iobase = ia->ia_iobase; - static u_char drq_conf[4] = { - 0x01, 0x02, -1, 0x08 + static u_char drq_conf[8] = { + 0x01, 0x02, -1, 0x08, -1, 0x20, 0x40, 0x80 }; + static u_char irq_conf[11] = { -1, -1, 0x01, -1, -1, 0x02, -1, 0x04, -1, 0x01, 0x08 }; - if (!SB_BASE_VALID(ia->ia_iobase)) { - printf("sb: configured iobase %d invalid\n", ia->ia_iobase); - return 0; - } - sc->sc_iobase = iobase; - sc->sc_irq = ia->ia_irq; - sc->sc_drq = ia->ia_drq; - if (sbdsp_probe(sc) == 0) { - DPRINTF(("sb: sbdsp probe failed\n")); + printf("%s: sbdsp probe failed\n", sc->sc_dev.dv_xname); return 0; } - + /* * Cannot auto-discover DMA channel. */ if (ISSBPROCLASS(sc)) { - if (!SBP_DRQ_VALID(ia->ia_drq)) { - printf("sb: configured dma chan %d invalid\n", ia->ia_drq); + if (!SBP_DRQ_VALID(sc->sc_drq8)) { + printf("%s: configured dma chan %d invalid\n", + sc->sc_dev.dv_xname, sc->sc_drq8); return 0; } - if (ISSB16CLASS(sc)) - sbdsp_mix_write(sc, SBP_SET_DRQ, drq_conf[ia->ia_drq]); - } - else { - if (!SB_DRQ_VALID(ia->ia_drq)) { - printf("sb: configured dma chan %d invalid\n", ia->ia_drq); + } else { + if (!SB_DRQ_VALID(sc->sc_drq8)) { + printf("%s: configured dma chan %d invalid\n", + sc->sc_dev.dv_xname, sc->sc_drq8); return 0; } } + if (ISSB16CLASS(sc)) { + if (sc->sc_drq16 == -1) + sc->sc_drq16 = sc->sc_drq8; + if (!SB16_DRQ_VALID(sc->sc_drq16)) { + printf("%s: configured dma chan %d invalid\n", + sc->sc_dev.dv_xname, sc->sc_drq16); + return 0; + } + } else + sc->sc_drq16 = sc->sc_drq8; + #ifdef NEWCONFIG /* * If the IRQ wasn't compiled in, auto-detect it. */ - if (ia->ia_irq == IRQUNK) { - ia->ia_irq = isa_discoverintr(sbforceintr, aux); + if (sc->sc_irq == IRQUNK) { + sc->sc_irq = isa_discoverintr(sbforceintr, sc); sbdsp_reset(sc); if (ISSBPROCLASS(sc)) { - if (!SBP_IRQ_VALID(ia->ia_irq)) { - printf("sb: couldn't auto-detect interrupt"); + if (!SBP_IRQ_VALID(sc->sc_irq)) { + printf("%s: couldn't auto-detect interrupt\n", + sc->sc_dev.dv_xname); return 0; } } else { - if (!SB_IRQ_VALID(ia->ia_irq)) { - printf("sb: couldn't auto-detect interrupt"); + if (!SB_IRQ_VALID(sc->sc_irq)) { + printf("%s: couldn't auto-detect interrupt\n"); + sc->sc_dev.dv_xname); return 0; } } } else #endif if (ISSBPROCLASS(sc)) { - if (!SBP_IRQ_VALID(ia->ia_irq)) { - printf("sb: configured irq %d invalid\n", ia->ia_irq); + if (!SBP_IRQ_VALID(sc->sc_irq)) { + printf("%s: configured irq %d invalid\n", + sc->sc_dev.dv_xname, sc->sc_irq); return 0; } - if (ISSB16CLASS(sc)) - sbdsp_mix_write(sc, SBP_SET_IRQ, irq_conf[ia->ia_irq]); - } - else { - if (!SB_IRQ_VALID(ia->ia_irq)) { - printf("sb: configured irq %d invalid\n", ia->ia_irq); + } else { + if (!SB_IRQ_VALID(sc->sc_irq)) { + printf("%s: configured irq %d invalid\n", + sc->sc_dev.dv_xname, sc->sc_irq); return 0; } } - if (ISSBPROCLASS(sc)) - ia->ia_iosize = SBP_NPORT; - else - ia->ia_iosize = SB_NPORT; + if (ISSB16CLASS(sc)) { +#if 0 + printf("%s: old drq conf %02x\n", sc->sc_dev.dv_xname, + sbdsp_mix_read(sc, SBP_SET_DRQ)); + printf("%s: try drq conf %02x\n", sc->sc_dev.dv_xname, + drq_conf[sc->sc_drq16] | drq_conf[sc->sc_drq8]); +#endif + sbdsp_mix_write(sc, SBP_SET_DRQ, + drq_conf[sc->sc_drq16] | drq_conf[sc->sc_drq8]); +#if 0 + printf("%s: new drq conf %02x\n", sc->sc_dev.dv_xname, + sbdsp_mix_read(sc, SBP_SET_DRQ)); +#endif + +#if 0 + printf("%s: old irq conf %02x\n", sc->sc_dev.dv_xname, + sbdsp_mix_read(sc, SBP_SET_IRQ)); + printf("%s: try irq conf %02x\n", sc->sc_dev.dv_xname, + irq_conf[sc->sc_irq]); +#endif + sbdsp_mix_write(sc, SBP_SET_IRQ, + irq_conf[sc->sc_irq]); +#if 0 + printf("%s: new irq conf %02x\n", sc->sc_dev.dv_xname, + sbdsp_mix_read(sc, SBP_SET_IRQ)); +#endif + } + return 1; } + +void +sbattach(sc) + struct sbdsp_softc *sc; +{ + int error; + + sc->sc_ih = isa_intr_establish(sc->sc_ic, sc->sc_irq, IST_EDGE, + IPL_AUDIO, sbdsp_intr, sc, sc->sc_dev.dv_xname); + + sbdsp_attach(sc); + + if ((error = audio_hardware_attach(&sb_hw_if, sc)) != 0) + printf("%s: could not attach to audio device driver (%d)\n", + sc->sc_dev.dv_xname, error); +} + #ifdef NEWCONFIG void sbforceintr(aux) void *aux; { static char dmabuf; - struct isa_attach_args *ia = aux; - int iobase = ia->ia_iobase; + struct sbdsp_softc *sc = aux; /* * Set up a DMA read of one byte. @@ -253,35 +275,14 @@ sbforceintr(aux) * it is needed (and you pay the latency). Also, you might * never need the buffer anyway.) */ - at_dma(DMAMODE_READ, &dmabuf, 1, ia->ia_drq); - if (sbdsp_wdsp(iobase, SB_DSP_RDMA) == 0) { - (void)sbdsp_wdsp(iobase, 0); - (void)sbdsp_wdsp(iobase, 0); + at_dma(DMAMODE_READ, &dmabuf, 1, sc->sc_drq8); + if (sbdsp_wdsp(sc, SB_DSP_RDMA) == 0) { + (void)sbdsp_wdsp(sc, 0); + (void)sbdsp_wdsp(sc, 0); } } #endif -/* - * Attach hardware to driver, attach hardware driver to audio - * pseudo-device driver . - */ -void -sbattach(parent, self, aux) - struct device *parent, *self; - void *aux; -{ - register struct sbdsp_softc *sc = (struct sbdsp_softc *)self; - struct isa_attach_args *ia = (struct isa_attach_args *)aux; - int err; - - sc->sc_ih = isa_intr_establish(ia->ia_ic, ia->ia_irq, IST_EDGE, - IPL_AUDIO, sbdsp_intr, sc, sc->sc_dev.dv_xname); - - sbdsp_attach(sc); - - if ((err = audio_hardware_attach(&sb_hw_if, sc)) != 0) - printf("sb: could not attach to audio pseudo-device driver (%d)\n", err); -} /* * Various routines to interface to higher level audio driver @@ -316,7 +317,7 @@ sb_getdev(addr, retp) strncpy(retp->name, "MV Jazz16", sizeof(retp->name)); else strncpy(retp->name, "SoundBlaster", sizeof(retp->name)); - sprintf(retp->version, "%d.%d", + sprintf(retp->version, "%d.%02d", SBVER_MAJOR(sc->sc_model), SBVER_MINOR(sc->sc_model)); strncpy(retp->config, "sb", sizeof(retp->config)); diff --git a/sys/dev/isa/sb_isa.c b/sys/dev/isa/sb_isa.c new file mode 100644 index 00000000000..da747efd05f --- /dev/null +++ b/sys/dev/isa/sb_isa.c @@ -0,0 +1,133 @@ +/* $OpenBSD: sb_isa.c,v 1.1 1997/07/10 23:06:37 provos Exp $ */ +/* $NetBSD: sb_isa.c,v 1.3 1997/03/20 11:03:11 mycroft Exp $ */ + +/* + * Copyright (c) 1991-1993 Regents of the University of California. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the Computer Systems + * Engineering Group at Lawrence Berkeley Laboratory. + * 4. Neither the name of the University nor of the Laboratory may be used + * to endorse or promote products derived from this software without + * specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + */ + +#include <sys/param.h> +#include <sys/systm.h> +#include <sys/errno.h> +#include <sys/ioctl.h> +#include <sys/syslog.h> +#include <sys/device.h> +#include <sys/proc.h> + +#include <sys/audioio.h> +#include <dev/audio_if.h> +#include <dev/mulaw.h> + +#include <dev/isa/isavar.h> +#include <dev/isa/isadmavar.h> + +#include <dev/isa/sbreg.h> +#include <dev/isa/sbvar.h> + +#include <dev/isa/sbdspvar.h> + +int sb_isa_match __P((struct device *, void *, void *)); +void sb_isa_attach __P((struct device *, struct device *, void *)); + +struct cfattach sb_isa_ca = { + sizeof(struct sbdsp_softc), sb_isa_match, sb_isa_attach +}; + +/* + * Probe / attach routines. + */ + +/* + * Probe for the soundblaster hardware. + */ +int +sb_isa_match(parent, match, aux) + struct device *parent; + void *match, *aux; +{ + /* + * Indirect brokedness! + */ + register struct sbdsp_softc *sc = match; + register struct isa_attach_args *ia = aux; + + if (!SB_BASE_VALID(ia->ia_iobase)) { + printf("sb: configured iobase 0x%x invalid\n", ia->ia_iobase); + return 0; + } + + sc->sc_iot = ia->ia_iot; + + /* Map i/o space [we map 24 ports which is the max of the sb and pro */ + if (bus_space_map(sc->sc_iot, ia->ia_iobase, SBP_NPORT, 0, + &sc->sc_ioh)) { + printf("sb: can't map i/o space 0x%x/%d in probe\n", + ia->ia_iobase, SBP_NPORT); + return 0; + } + + /* + * Indirect brokedness! + */ + sc->sc_iobase = ia->ia_iobase; + sc->sc_irq = ia->ia_irq; + sc->sc_drq8 = ia->ia_drq; + sc->sc_drq16 = -1; /* XXX */ + sc->sc_ic = ia->ia_ic; + + if (!sbmatch(sc)) { + bus_space_unmap(sc->sc_iot, sc->sc_ioh, SBP_NPORT); + return 0; + } + + if (ISSBPROCLASS(sc)) + ia->ia_iosize = SBP_NPORT; + else + ia->ia_iosize = SB_NPORT; + + ia->ia_irq = sc->sc_irq; + + return 1; +} + + +/* + * Attach hardware to driver, attach hardware driver to audio + * pseudo-device driver . + */ +void +sb_isa_attach(parent, self, aux) + struct device *parent, *self; + void *aux; +{ + sbattach((struct sbdsp_softc *) self); +} diff --git a/sys/dev/isa/sbdsp.c b/sys/dev/isa/sbdsp.c index e55dff2f152..35a24e7b41e 100644 --- a/sys/dev/isa/sbdsp.c +++ b/sys/dev/isa/sbdsp.c @@ -1,4 +1,4 @@ -/* $OpenBSD: sbdsp.c,v 1.9 1997/01/03 00:09:59 kstailey Exp $ */ +/* $OpenBSD: sbdsp.c,v 1.10 1997/07/10 23:06:38 provos Exp $ */ /* $NetBSD: sbdsp.c,v 1.30 1996/10/25 07:25:48 fvdl Exp $ */ /* @@ -34,6 +34,7 @@ * SUCH DAMAGE. * */ + /* * SoundBlaster Pro code provided by John Kohl, based on lots of * information he gleaned from Steve Haehnichen <steve@vigra.com>'s @@ -121,10 +122,10 @@ u_int sbdsp_jazz16_probe __P((struct sbdsp_softc *)); #define SB_DAC_LS_MAX 0xd4 /* 22727 Hz */ #define SB_DAC_HS_MAX 0xea /* 45454 Hz */ -int sbdsp16_wait __P((int)); +int sbdsp16_wait __P((struct sbdsp_softc *)); void sbdsp_to __P((void *)); void sbdsp_pause __P((struct sbdsp_softc *)); -int sbdsp_setrate __P((struct sbdsp_softc *, int, int, int *)); +int sbdsp16_setrate __P((struct sbdsp_softc *, int, int, int *)); int sbdsp_tctosr __P((struct sbdsp_softc *, int)); int sbdsp_set_timeconst __P((struct sbdsp_softc *, int)); @@ -139,11 +140,11 @@ sb_printsc(sc) { int i; - printf("open %d dmachan %d iobase %x\n", - sc->sc_open, sc->sc_drq, sc->sc_iobase); + printf("open %d dmachan %d/%d/%d iobase %x\n", + sc->sc_open, sc->dmachan, sc->sc_drq8, sc->sc_drq16, sc->sc_iobase); printf("irate %d itc %d imode %d orate %d otc %d omode %d encoding %x\n", sc->sc_irate, sc->sc_itc, sc->sc_imode, - sc->sc_orate, sc->sc_otc, sc->sc_omode, sc->encoding); + sc->sc_orate, sc->sc_otc, sc->sc_omode, sc->sc_encoding); printf("outport %d inport %d spkron %d nintr %lu\n", sc->out_port, sc->in_port, sc->spkr_state, sc->sc_interrupts); printf("precision %d channels %d intr %p arg %p\n", @@ -172,10 +173,11 @@ sbdsp_probe(sc) return 0; } /* if flags set, go and probe the jazz16 stuff */ - if (sc->sc_dev.dv_cfdata->cf_flags != 0) + if (sc->sc_dev.dv_cfdata->cf_flags != 0) { sc->sc_model = sbdsp_jazz16_probe(sc); - else + } else { sc->sc_model = sbversion(sc); + } return 1; } @@ -197,34 +199,57 @@ sbdsp_jazz16_probe(sc) -1, 0x03, -1, 0x04}; u_int rval = sbversion(sc); - register int iobase = sc->sc_iobase; + bus_space_tag_t iot = sc->sc_iot; + bus_space_handle_t ioh; - if (jazz16_drq_conf[sc->sc_drq] == (u_char)-1 || - jazz16_irq_conf[sc->sc_irq] == (u_char)-1) - return rval; /* give up, we can't do it. */ - outb(JAZZ16_CONFIG_PORT, JAZZ16_WAKEUP); + DPRINTF(("jazz16 probe\n")); + + if (bus_space_map(iot, JAZZ16_CONFIG_PORT, 1, 0, &ioh)) { + DPRINTF(("bus map failed\n")); + return rval; + } + + if (jazz16_drq_conf[sc->sc_drq8] == (u_char)-1 || + jazz16_irq_conf[sc->sc_irq] == (u_char)-1) { + DPRINTF(("drq/irq check failed\n")); + goto done; /* give up, we can't do it. */ + } + + bus_space_write_1(iot, ioh, 0, JAZZ16_WAKEUP); delay(10000); /* delay 10 ms */ - outb(JAZZ16_CONFIG_PORT, JAZZ16_SETBASE); - outb(JAZZ16_CONFIG_PORT, iobase & 0x70); + bus_space_write_1(iot, ioh, 0, JAZZ16_SETBASE); + bus_space_write_1(iot, ioh, 0, sc->sc_iobase & 0x70); - if (sbdsp_reset(sc) < 0) - return rval; /* XXX? what else could we do? */ + if (sbdsp_reset(sc) < 0) { + DPRINTF(("sbdsp_reset check failed\n")); + goto done; /* XXX? what else could we do? */ + } - if (sbdsp_wdsp(iobase, JAZZ16_READ_VER)) - return rval; - if (sbdsp_rdsp(iobase) != JAZZ16_VER_JAZZ) - return rval; + if (sbdsp_wdsp(sc, JAZZ16_READ_VER)) { + DPRINTF(("read16 setup failed\n")); + goto done; + } - if (sbdsp_wdsp(iobase, JAZZ16_SET_DMAINTR) || - /* set both 8 & 16-bit drq to same channel, it works fine. */ - sbdsp_wdsp(iobase, - (jazz16_drq_conf[sc->sc_drq] << 4) | - jazz16_drq_conf[sc->sc_drq]) || - sbdsp_wdsp(iobase, jazz16_irq_conf[sc->sc_irq])) { - DPRINTF(("sbdsp: can't write jazz16 probe stuff")); - return rval; + if (sbdsp_rdsp(sc) != JAZZ16_VER_JAZZ) { + DPRINTF(("read16 failed\n")); + goto done; } - return (rval | MODEL_JAZZ16); + + /* XXX set both 8 & 16-bit drq to same channel, it works fine. */ + sc->sc_drq16 = sc->sc_drq8; + if (sbdsp_wdsp(sc, JAZZ16_SET_DMAINTR) || + sbdsp_wdsp(sc, (jazz16_drq_conf[sc->sc_drq16] << 4) | + jazz16_drq_conf[sc->sc_drq8]) || + sbdsp_wdsp(sc, jazz16_irq_conf[sc->sc_irq])) { + DPRINTF(("sbdsp: can't write jazz16 probe stuff\n")); + } else { + DPRINTF(("jazz16 detected!\n")); + rval |= MODEL_JAZZ16; + } + +done: + bus_space_unmap(iot, ioh, 1); + return rval; } /* @@ -243,9 +268,9 @@ sbdsp_attach(sc) sc->sc_itc = sc->sc_otc = SB_8K; else sc->sc_itc = sc->sc_otc = SB_8K; + sc->sc_encoding = AUDIO_ENCODING_ULAW; sc->sc_precision = 8; sc->sc_channels = 1; - sc->encoding = AUDIO_ENCODING_ULAW; (void) sbdsp_set_in_port(sc, SB_MIC_PORT); (void) sbdsp_set_out_port(sc, SB_SPEAKER); @@ -273,18 +298,6 @@ sbdsp_attach(sc) printf(": dsp v%d.%02d%s\n", SBVER_MAJOR(sc->sc_model), SBVER_MINOR(sc->sc_model), ISJAZZ16(sc) ? ": <Jazz16>" : ""); - -#ifdef notyet - sbdsp_mix_write(sc, SBP_SET_IRQ, 0x04); - sbdsp_mix_write(sc, SBP_SET_DRQ, 0x22); - - printf("sbdsp_attach: irq=%02x, drq=%02x\n", - sbdsp_mix_read(sc, SBP_SET_IRQ), - sbdsp_mix_read(sc, SBP_SET_DRQ)); -#else - if (ISSB16CLASS(sc)) - sc->sc_model = 0x0300; -#endif } /* @@ -297,10 +310,12 @@ sbdsp_mix_write(sc, mixerport, val) int mixerport; int val; { - int iobase = sc->sc_iobase; - outb(iobase + SBP_MIXER_ADDR, mixerport); + bus_space_tag_t iot = sc->sc_iot; + bus_space_handle_t ioh = sc->sc_ioh; + + bus_space_write_1(iot, ioh, SBP_MIXER_ADDR, mixerport); delay(10); - outb(iobase + SBP_MIXER_DATA, val); + bus_space_write_1(iot, ioh, SBP_MIXER_DATA, val); delay(30); } @@ -309,10 +324,12 @@ sbdsp_mix_read(sc, mixerport) struct sbdsp_softc *sc; int mixerport; { - int iobase = sc->sc_iobase; - outb(iobase + SBP_MIXER_ADDR, mixerport); + bus_space_tag_t iot = sc->sc_iot; + bus_space_handle_t ioh = sc->sc_ioh; + + bus_space_write_1(iot, ioh, SBP_MIXER_ADDR, mixerport); delay(10); - return inb(iobase + SBP_MIXER_DATA); + return bus_space_read_1(iot, ioh, SBP_MIXER_DATA); } int @@ -323,7 +340,7 @@ sbdsp_set_in_sr(addr, sr) register struct sbdsp_softc *sc = addr; if (ISSB16CLASS(sc)) - return (sbdsp_setrate(sc, sr, SB_INPUT_RATE, &sc->sc_irate)); + return (sbdsp16_setrate(sc, sr, SB_INPUT_RATE, &sc->sc_irate)); else return (sbdsp_srtotc(sc, sr, SB_INPUT_RATE, &sc->sc_itc, &sc->sc_imode)); } @@ -348,7 +365,7 @@ sbdsp_set_out_sr(addr, sr) register struct sbdsp_softc *sc = addr; if (ISSB16CLASS(sc)) - return (sbdsp_setrate(sc, sr, SB_OUTPUT_RATE, &sc->sc_orate)); + return (sbdsp16_setrate(sc, sr, SB_OUTPUT_RATE, &sc->sc_orate)); else return (sbdsp_srtotc(sc, sr, SB_OUTPUT_RATE, &sc->sc_otc, &sc->sc_omode)); } @@ -386,53 +403,38 @@ sbdsp_query_encoding(addr, fp) } int -sbdsp_set_encoding(addr, encoding) +sbdsp_set_format(addr, encoding, precision) void *addr; - u_int encoding; + u_int encoding, precision; { register struct sbdsp_softc *sc = addr; switch (encoding) { case AUDIO_ENCODING_ULAW: - sc->encoding = AUDIO_ENCODING_ULAW; - break; - case AUDIO_ENCODING_LINEAR: - sc->encoding = AUDIO_ENCODING_LINEAR; + case AUDIO_ENCODING_PCM16: + case AUDIO_ENCODING_PCM8: break; default: return (EINVAL); } - return (0); -} + if (precision == 16) + if (!ISSB16CLASS(sc) && !ISJAZZ16(sc)) + return (EINVAL); -int -sbdsp_get_encoding(addr) - void *addr; -{ - register struct sbdsp_softc *sc = addr; + sc->sc_encoding = encoding; + sc->sc_precision = precision; - return (sc->encoding); + return (0); } int -sbdsp_set_precision(addr, precision) +sbdsp_get_encoding(addr) void *addr; - u_int precision; { register struct sbdsp_softc *sc = addr; - if (ISSB16CLASS(sc) || ISJAZZ16(sc)) { - if (precision != 16 && precision != 8) - return (EINVAL); - sc->sc_precision = precision; - } else { - if (precision != 8) - return (EINVAL); - sc->sc_precision = precision; - } - - return (0); + return (sc->sc_encoding); } int @@ -487,6 +489,7 @@ sbdsp_set_ifilter(addr, which) register struct sbdsp_softc *sc = addr; int mixval; + /* XXXX SB16 */ if (ISSBPROCLASS(sc)) { mixval = sbdsp_mix_read(sc, SBP_INFILTER) & ~SBP_IFILTER_MASK; switch (which) { @@ -515,6 +518,7 @@ sbdsp_get_ifilter(addr) { register struct sbdsp_softc *sc = addr; + /* XXXX SB16 */ if (ISSBPROCLASS(sc)) { sc->in_filter = sbdsp_mix_read(sc, SBP_INFILTER) & SBP_IFILTER_MASK; @@ -593,6 +597,7 @@ sbdsp_set_in_port(addr, port) sc->in_port = port; /* Just record it */ + /* XXXX SB16 */ if (ISSBPROCLASS(sc)) { /* record from that port */ sbdsp_mix_write(sc, SBP_RECORD_SOURCE, @@ -643,23 +648,14 @@ sbdsp_round_blocksize(addr, blk) sc->sc_last_hs_size = 0; - /* Higher speeds need bigger blocks to avoid popping and silence gaps. */ - if (blk < NBPG/4 || blk > NBPG/2) { - if (ISSB16CLASS(sc)) { - if (sc->sc_orate > 8000 || sc->sc_irate > 8000) - blk = NBPG/2; - } else { - if (sc->sc_otc > SB_8K || sc->sc_itc > SB_8K) - blk = NBPG/2; - } - } - /* don't try to DMA too much at once, though. */ + /* Don't try to DMA too much at once. */ if (blk > NBPG) blk = NBPG; - if (sc->sc_channels == 2) - return (blk & ~1); /* must be even to preserve stereo separation */ - else - return (blk); /* Anything goes :-) */ + + /* Round to a multiple of the sample size. */ + blk &= -(sc->sc_channels * sc->sc_precision / 8); + + return (blk); } int @@ -700,13 +696,7 @@ sbdsp_commit_settings(addr) SB_OUTPUT_RATE, &sc->sc_otc, &sc->sc_omode); } - if (ISSB16CLASS(sc) || ISJAZZ16(sc)) { - if (sc->encoding == AUDIO_ENCODING_ULAW && - sc->sc_precision == 16) { - sc->sc_precision = 8; - return EINVAL; /* XXX what should we really do? */ - } - } + /* * XXX * Should wait for chip to be idle. @@ -731,7 +721,7 @@ sbdsp_open(sc, dev, flags) sc->sc_open = 1; sc->sc_mintr = 0; if (ISSBPROCLASS(sc) && - sbdsp_wdsp(sc->sc_iobase, SB_DSP_RECORD_MONO) < 0) { + sbdsp_wdsp(sc, SB_DSP_RECORD_MONO) < 0) { DPRINTF(("sbdsp_open: can't set mono mode\n")); /* we'll readjust when it's time for DMA. */ } @@ -776,11 +766,12 @@ int sbdsp_reset(sc) register struct sbdsp_softc *sc; { - register int iobase = sc->sc_iobase; + bus_space_tag_t iot = sc->sc_iot; + bus_space_handle_t ioh = sc->sc_ioh; sc->sc_intr = 0; if (sc->sc_dmadir != SB_DMA_NONE) { - isa_dmaabort(sc->sc_drq); + isa_dmaabort(sc->dmachan); sc->sc_dmadir = SB_DMA_NONE; } sc->sc_last_hs_size = 0; @@ -790,25 +781,27 @@ sbdsp_reset(sc) * We pulse a reset signal into the card. * Gee, what a brilliant hardware design. */ - outb(iobase + SBP_DSP_RESET, 1); + bus_space_write_1(iot, ioh, SBP_DSP_RESET, 1); delay(10); - outb(iobase + SBP_DSP_RESET, 0); + bus_space_write_1(iot, ioh, SBP_DSP_RESET, 0); delay(30); - if (sbdsp_rdsp(iobase) != SB_MAGIC) + if (sbdsp_rdsp(sc) != SB_MAGIC) return -1; return 0; } int -sbdsp16_wait(iobase) - int iobase; +sbdsp16_wait(sc) + struct sbdsp_softc *sc; { + bus_space_tag_t iot = sc->sc_iot; + bus_space_handle_t ioh = sc->sc_ioh; register int i; for (i = SBDSP_NPOLL; --i >= 0; ) { register u_char x; - x = inb(iobase + SBP_DSP_WSTAT); + x = bus_space_read_1(iot, ioh, SBP_DSP_WSTAT); delay(10); if ((x & SB_DSP_BUSY) == 0) continue; @@ -824,17 +817,21 @@ sbdsp16_wait(iobase) * polling loop and wait until it can take the byte. */ int -sbdsp_wdsp(int iobase, int v) +sbdsp_wdsp(sc, v) + struct sbdsp_softc *sc; + int v; { + bus_space_tag_t iot = sc->sc_iot; + bus_space_handle_t ioh = sc->sc_ioh; register int i; for (i = SBDSP_NPOLL; --i >= 0; ) { register u_char x; - x = inb(iobase + SBP_DSP_WSTAT); + x = bus_space_read_1(iot, ioh, SBP_DSP_WSTAT); delay(10); if ((x & SB_DSP_BUSY) != 0) continue; - outb(iobase + SBP_DSP_WRITE, v); + bus_space_write_1(iot, ioh, SBP_DSP_WRITE, v); delay(10); return 0; } @@ -846,17 +843,20 @@ sbdsp_wdsp(int iobase, int v) * Read a byte from the DSP, using polling. */ int -sbdsp_rdsp(int iobase) +sbdsp_rdsp(sc) + struct sbdsp_softc *sc; { + bus_space_tag_t iot = sc->sc_iot; + bus_space_handle_t ioh = sc->sc_ioh; register int i; for (i = SBDSP_NPOLL; --i >= 0; ) { register u_char x; - x = inb(iobase + SBP_DSP_RSTAT); + x = bus_space_read_1(iot, ioh, SBP_DSP_RSTAT); delay(10); if ((x & SB_DSP_READY) == 0) continue; - x = inb(iobase + SBP_DSP_READ); + x = bus_space_read_1(iot, ioh, SBP_DSP_READ); delay(10); return x; } @@ -899,7 +899,7 @@ void sbdsp_spkron(sc) struct sbdsp_softc *sc; { - (void)sbdsp_wdsp(sc->sc_iobase, SB_DSP_SPKR_ON); + (void)sbdsp_wdsp(sc, SB_DSP_SPKR_ON); sbdsp_pause(sc); } @@ -910,7 +910,7 @@ void sbdsp_spkroff(sc) struct sbdsp_softc *sc; { - (void)sbdsp_wdsp(sc->sc_iobase, SB_DSP_SPKR_OFF); + (void)sbdsp_wdsp(sc, SB_DSP_SPKR_OFF); sbdsp_pause(sc); } @@ -922,13 +922,12 @@ short sbversion(sc) struct sbdsp_softc *sc; { - register int iobase = sc->sc_iobase; short v; - if (sbdsp_wdsp(iobase, SB_DSP_VERSION) < 0) + if (sbdsp_wdsp(sc, SB_DSP_VERSION) < 0) return 0; - v = sbdsp_rdsp(iobase) << 8; - v |= sbdsp_rdsp(iobase); + v = sbdsp_rdsp(sc) << 8; + v |= sbdsp_rdsp(sc); return ((v >= 0) ? v : 0); } @@ -957,12 +956,12 @@ sbdsp_contdma(addr) DPRINTF(("sbdsp_contdma: sc=0x%x\n", sc)); /* XXX how do we reinitialize the DMA controller state? do we care? */ - (void)sbdsp_wdsp(sc->sc_iobase, SB_DSP_CONT); + (void)sbdsp_wdsp(sc, SB_DSP_CONT); return(0); } int -sbdsp_setrate(sc, sr, isdac, ratep) +sbdsp16_setrate(sc, sr, isdac, ratep) register struct sbdsp_softc *sc; int sr; int isdac; @@ -973,7 +972,7 @@ sbdsp_setrate(sc, sr, isdac, ratep) * XXXX * More checks here? */ - if (sr < 5000 || sr > 44100) + if (sr < 5000 || sr > 45454) return (EINVAL); *ratep = sr; return (0); @@ -1083,8 +1082,6 @@ sbdsp_set_timeconst(sc, tc) register struct sbdsp_softc *sc; int tc; { - register int iobase; - /* * A SBPro in stereo mode uses time constants at double the * actual rate. @@ -1094,9 +1091,8 @@ sbdsp_set_timeconst(sc, tc) DPRINTF(("sbdsp_set_timeconst: sc=%p tc=%d\n", sc, tc)); - iobase = sc->sc_iobase; - if (sbdsp_wdsp(iobase, SB_DSP_TIMECONST) < 0 || - sbdsp_wdsp(iobase, tc) < 0) + if (sbdsp_wdsp(sc, SB_DSP_TIMECONST) < 0 || + sbdsp_wdsp(sc, tc) < 0) return (EIO); return (0); @@ -1111,7 +1107,6 @@ sbdsp_dma_input(addr, p, cc, intr, arg) void *arg; { register struct sbdsp_softc *sc = addr; - register int iobase; #ifdef AUDIO_DEBUG if (sbdspdebug > 1) @@ -1122,16 +1117,15 @@ sbdsp_dma_input(addr, p, cc, intr, arg) return EIO; } - iobase = sc->sc_iobase; if (sc->sc_dmadir != SB_DMA_IN) { if (ISSBPRO(sc)) { if (sc->sc_channels == 2) { if (ISJAZZ16(sc) && sc->sc_precision == 16) { - if (sbdsp_wdsp(iobase, + if (sbdsp_wdsp(sc, JAZZ16_RECORD_STEREO) < 0) { goto badmode; } - } else if (sbdsp_wdsp(iobase, + } else if (sbdsp_wdsp(sc, SB_DSP_RECORD_STEREO) < 0) goto badmode; sbdsp_mix_write(sc, SBP_INFILTER, @@ -1139,12 +1133,12 @@ sbdsp_dma_input(addr, p, cc, intr, arg) ~SBP_IFILTER_MASK) | SBP_FILTER_OFF); } else { if (ISJAZZ16(sc) && sc->sc_precision == 16) { - if (sbdsp_wdsp(iobase, + if (sbdsp_wdsp(sc, JAZZ16_RECORD_MONO) < 0) { goto badmode; } - } else if (sbdsp_wdsp(iobase, SB_DSP_RECORD_MONO) < 0) + } else if (sbdsp_wdsp(sc, SB_DSP_RECORD_MONO) < 0) goto badmode; sbdsp_mix_write(sc, SBP_INFILTER, (sbdsp_mix_read(sc, SBP_INFILTER) & @@ -1153,56 +1147,65 @@ sbdsp_dma_input(addr, p, cc, intr, arg) } if (ISSB16CLASS(sc)) { - if (sbdsp_wdsp(iobase, SB_DSP16_INPUTRATE) < 0 || - sbdsp_wdsp(iobase, sc->sc_irate >> 8) < 0 || - sbdsp_wdsp(iobase, sc->sc_irate) < 0) + if (sbdsp_wdsp(sc, SB_DSP16_INPUTRATE) < 0 || + sbdsp_wdsp(sc, sc->sc_irate >> 8) < 0 || + sbdsp_wdsp(sc, sc->sc_irate) < 0) goto giveup; } else sbdsp_set_timeconst(sc, sc->sc_itc); + sc->sc_dmadir = SB_DMA_IN; + sc->dmaflags = DMAMODE_READ; + if (ISSB2CLASS(sc)) + sc->dmaflags |= DMAMODE_LOOP; + } else { + /* Already started; just return. */ + if (ISSB2CLASS(sc)) + return 0; } - isa_dmastart(DMAMODE_READ, p, cc, sc->sc_drq); + sc->dmaaddr = p; + sc->dmacnt = ISSB2CLASS(sc) ? (NBPG/cc)*cc : cc; + sc->dmachan = sc->sc_precision == 16 ? sc->sc_drq16 : sc->sc_drq8; + isa_dmastart(sc->dmaflags, sc->dmaaddr, sc->dmacnt, sc->dmachan); sc->sc_intr = intr; sc->sc_arg = arg; - sc->dmaflags = DMAMODE_READ; - sc->dmaaddr = p; - sc->dmacnt = cc; /* DMA controller is strange...? */ - if ((ISSB16CLASS(sc) && sc->sc_precision == 16) || - (ISJAZZ16(sc) && sc->sc_drq > 3)) + if (sc->sc_precision == 16) cc >>= 1; --cc; if (ISSB16CLASS(sc)) { - if (sbdsp_wdsp(iobase, sc->sc_precision == 16 ? SB_DSP16_RDMA_16 : - SB_DSP16_RDMA_8) < 0 || - sbdsp_wdsp(iobase, (sc->sc_precision == 16 ? 0x10 : 0x00) | + if (sbdsp_wdsp(sc, sc->sc_precision == 16 ? SB_DSP16_RDMA_16 : + SB_DSP16_RDMA_8) < 0 || + sbdsp_wdsp(sc, (sc->sc_precision == 16 ? 0x10 : 0x00) | (sc->sc_channels == 2 ? 0x20 : 0x00)) < 0 || - sbdsp16_wait(iobase) || - sbdsp_wdsp(iobase, cc) < 0 || - sbdsp_wdsp(iobase, cc >> 8) < 0) { + sbdsp16_wait(sc) || + sbdsp_wdsp(sc, cc) < 0 || + sbdsp_wdsp(sc, cc >> 8) < 0) { DPRINTF(("sbdsp_dma_input: SB16 DMA start failed\n")); goto giveup; } - } else if (sc->sc_imode == SB_ADAC_LS) { - if (sbdsp_wdsp(iobase, SB_DSP_RDMA) < 0 || - sbdsp_wdsp(iobase, cc) < 0 || - sbdsp_wdsp(iobase, cc >> 8) < 0) { - DPRINTF(("sbdsp_dma_input: LS DMA start failed\n")); - goto giveup; - } - } else { + } else if (ISSB2CLASS(sc)) { if (cc != sc->sc_last_hs_size) { - if (sbdsp_wdsp(iobase, SB_DSP_BLOCKSIZE) < 0 || - sbdsp_wdsp(iobase, cc) < 0 || - sbdsp_wdsp(iobase, cc >> 8) < 0) { - DPRINTF(("sbdsp_dma_input: HS DMA start failed\n")); + if (sbdsp_wdsp(sc, SB_DSP_BLOCKSIZE) < 0 || + sbdsp_wdsp(sc, cc) < 0 || + sbdsp_wdsp(sc, cc >> 8) < 0) { + DPRINTF(("sbdsp_dma_input: SB2 DMA start failed\n")); goto giveup; } sc->sc_last_hs_size = cc; } - if (sbdsp_wdsp(iobase, SB_DSP_HS_INPUT) < 0) { - DPRINTF(("sbdsp_dma_input: HS DMA restart failed\n")); + if (sbdsp_wdsp(sc, + sc->sc_imode == SB_ADAC_LS ? SB_DSP_RDMA_LOOP : + SB_DSP_HS_INPUT) < 0) { + DPRINTF(("sbdsp_dma_input: SB2 DMA restart failed\n")); + goto giveup; + } + } else { + if (sbdsp_wdsp(sc, SB_DSP_RDMA) < 0 || + sbdsp_wdsp(sc, cc) < 0 || + sbdsp_wdsp(sc, cc >> 8) < 0) { + DPRINTF(("sbdsp_dma_input: SB1 DMA start failed\n")); goto giveup; } } @@ -1227,7 +1230,6 @@ sbdsp_dma_output(addr, p, cc, intr, arg) void *arg; { register struct sbdsp_softc *sc = addr; - register int iobase; #ifdef AUDIO_DEBUG if (sbdspdebug > 1) @@ -1238,7 +1240,6 @@ sbdsp_dma_output(addr, p, cc, intr, arg) return EIO; } - iobase = sc->sc_iobase; if (sc->sc_dmadir != SB_DMA_OUT) { if (ISSBPRO(sc)) { /* make sure we re-set stereo mixer bit when we start @@ -1250,12 +1251,12 @@ sbdsp_dma_output(addr, p, cc, intr, arg) /* Yes, we write the record mode to set 16-bit playback mode. weird, huh? */ if (sc->sc_precision == 16) { - sbdsp_wdsp(iobase, + sbdsp_wdsp(sc, sc->sc_channels == 2 ? JAZZ16_RECORD_STEREO : JAZZ16_RECORD_MONO); } else { - sbdsp_wdsp(iobase, + sbdsp_wdsp(sc, sc->sc_channels == 2 ? SB_DSP_RECORD_STEREO : SB_DSP_RECORD_MONO); @@ -1264,56 +1265,65 @@ sbdsp_dma_output(addr, p, cc, intr, arg) } if (ISSB16CLASS(sc)) { - if (sbdsp_wdsp(iobase, SB_DSP16_OUTPUTRATE) < 0 || - sbdsp_wdsp(iobase, sc->sc_orate >> 8) < 0 || - sbdsp_wdsp(iobase, sc->sc_orate) < 0) + if (sbdsp_wdsp(sc, SB_DSP16_OUTPUTRATE) < 0 || + sbdsp_wdsp(sc, sc->sc_orate >> 8) < 0 || + sbdsp_wdsp(sc, sc->sc_orate) < 0) goto giveup; } else sbdsp_set_timeconst(sc, sc->sc_otc); + sc->sc_dmadir = SB_DMA_OUT; + sc->dmaflags = DMAMODE_WRITE; + if (ISSB2CLASS(sc)) + sc->dmaflags |= DMAMODE_LOOP; + } else { + /* Already started; just return. */ + if (ISSB2CLASS(sc)) + return 0; } - isa_dmastart(DMAMODE_WRITE, p, cc, sc->sc_drq); + sc->dmaaddr = p; + sc->dmacnt = ISSB2CLASS(sc) ? (NBPG/cc)*cc : cc; + sc->dmachan = sc->sc_precision == 16 ? sc->sc_drq16 : sc->sc_drq8; + isa_dmastart(sc->dmaflags, sc->dmaaddr, sc->dmacnt, sc->dmachan); sc->sc_intr = intr; sc->sc_arg = arg; - sc->dmaflags = DMAMODE_WRITE; - sc->dmaaddr = p; - sc->dmacnt = cc; /* a vagary of how DMA works, apparently. */ - if ((ISSB16CLASS(sc) && sc->sc_precision == 16) || - (ISJAZZ16(sc) && sc->sc_drq > 3)) + if (sc->sc_precision == 16) cc >>= 1; --cc; if (ISSB16CLASS(sc)) { - if (sbdsp_wdsp(iobase, sc->sc_precision == 16 ? SB_DSP16_WDMA_16 : - SB_DSP16_WDMA_8) < 0 || - sbdsp_wdsp(iobase, (sc->sc_precision == 16 ? 0x10 : 0x00) | + if (sbdsp_wdsp(sc, sc->sc_precision == 16 ? SB_DSP16_WDMA_16 : + SB_DSP16_WDMA_8) < 0 || + sbdsp_wdsp(sc, (sc->sc_precision == 16 ? 0x10 : 0x00) | (sc->sc_channels == 2 ? 0x20 : 0x00)) < 0 || - sbdsp16_wait(iobase) || - sbdsp_wdsp(iobase, cc) < 0 || - sbdsp_wdsp(iobase, cc >> 8) < 0) { + sbdsp16_wait(sc) || + sbdsp_wdsp(sc, cc) < 0 || + sbdsp_wdsp(sc, cc >> 8) < 0) { DPRINTF(("sbdsp_dma_output: SB16 DMA start failed\n")); goto giveup; } - } else if (sc->sc_omode == SB_ADAC_LS) { - if (sbdsp_wdsp(iobase, SB_DSP_WDMA) < 0 || - sbdsp_wdsp(iobase, cc) < 0 || - sbdsp_wdsp(iobase, cc >> 8) < 0) { - DPRINTF(("sbdsp_dma_output: LS DMA start failed\n")); - goto giveup; - } - } else { + } else if (ISSB2CLASS(sc)) { if (cc != sc->sc_last_hs_size) { - if (sbdsp_wdsp(iobase, SB_DSP_BLOCKSIZE) < 0 || - sbdsp_wdsp(iobase, cc) < 0 || - sbdsp_wdsp(iobase, cc >> 8) < 0) { - DPRINTF(("sbdsp_dma_output: HS DMA start failed\n")); + if (sbdsp_wdsp(sc, SB_DSP_BLOCKSIZE) < 0 || + sbdsp_wdsp(sc, cc) < 0 || + sbdsp_wdsp(sc, cc >> 8) < 0) { + DPRINTF(("sbdsp_dma_output: SB2 DMA start failed\n")); goto giveup; } sc->sc_last_hs_size = cc; } - if (sbdsp_wdsp(iobase, SB_DSP_HS_OUTPUT) < 0) { - DPRINTF(("sbdsp_dma_output: HS DMA restart failed\n")); + if (sbdsp_wdsp(sc, + sc->sc_omode == SB_ADAC_LS ? SB_DSP_WDMA_LOOP : + SB_DSP_HS_OUTPUT) < 0) { + DPRINTF(("sbdsp_dma_output: SB2 DMA restart failed\n")); + goto giveup; + } + } else { + if (sbdsp_wdsp(sc, SB_DSP_WDMA) < 0 || + sbdsp_wdsp(sc, cc) < 0 || + sbdsp_wdsp(sc, cc >> 8) < 0) { + DPRINTF(("sbdsp_dma_output: SB1 DMA start failed\n")); goto giveup; } } @@ -1342,27 +1352,32 @@ sbdsp_intr(arg) if (sbdspdebug > 1) Dprintf("sbdsp_intr: intr=0x%x\n", sc->sc_intr); #endif + if (ISSB16CLASS(sc)) { + x = sbdsp_mix_read(sc, SBP_IRQ_STATUS); + if ((x & 3) == 0) + return 0; + } /* isa_dmafinished() moved to isadma.c */ sc->sc_interrupts++; - /* clear interrupt */ -#ifdef notyet - x = sbdsp_mix_read(sc, 0x82); - x = inb(sc->sc_iobase + 15); -#endif - x = inb(sc->sc_iobase + SBP_DSP_RSTAT); delay(10); #if 0 if (sc->sc_mintr != 0) { - x = sbdsp_rdsp(sc->sc_iobase); + x = sbdsp_rdsp(sc); (*sc->sc_mintr)(sc->sc_arg, x); } else #endif if (sc->sc_intr != 0) { - isa_dmadone(sc->dmaflags, sc->dmaaddr, sc->dmacnt, sc->sc_drq); + /* clear interrupt */ + x = bus_space_read_1(sc->sc_iot, sc->sc_ioh, + sc->sc_precision == 16 ? SBP_DSP_IRQACK16 : + SBP_DSP_IRQACK8); + if (!ISSB2CLASS(sc)) + isa_dmadone(sc->dmaflags, sc->dmaaddr, sc->dmacnt, + sc->dmachan); (*sc->sc_intr)(sc->sc_arg); - } - else + } else { return 0; + } return 1; } @@ -1385,7 +1400,7 @@ sbdsp_set_midi_mode(sc, intr, arg) void *arg; { - sbdsp_wdsp(sc->sc_iobase, SB_MIDI_UART_INTR); + sbdsp_wdsp(sc, SB_MIDI_UART_INTR); sc->sc_mintr = intr; sc->sc_intr = 0; sc->sc_arg = arg; @@ -1400,32 +1415,11 @@ sbdsp_midi_output(sc, v) int v; { - if (sbdsp_wdsp(sc->sc_iobase, v) < 0) + if (sbdsp_wdsp(sc, v) < 0) ++sberr.wmidi; } #endif -u_int -sbdsp_get_silence(encoding) - int encoding; -{ -#define ULAW_SILENCE 0x7f -#define LINEAR_SILENCE 0 - u_int auzero; - - switch (encoding) { - case AUDIO_ENCODING_ULAW: - auzero = ULAW_SILENCE; - break; - case AUDIO_ENCODING_PCM16: - default: - auzero = LINEAR_SILENCE; - break; - } - - return (auzero); -} - int sbdsp_setfd(addr, flag) void *addr; diff --git a/sys/dev/isa/sbdspvar.h b/sys/dev/isa/sbdspvar.h index e25349a2626..5279e227ef5 100644 --- a/sys/dev/isa/sbdspvar.h +++ b/sys/dev/isa/sbdspvar.h @@ -1,4 +1,4 @@ -/* $OpenBSD: sbdspvar.h,v 1.6 1996/11/29 22:55:07 niklas Exp $ */ +/* $OpenBSD: sbdspvar.h,v 1.7 1997/07/10 23:06:38 provos Exp $ */ /* $NetBSD: sbdspvar.h,v 1.13 1996/04/29 20:28:50 christos Exp $ */ /* @@ -76,11 +76,14 @@ struct sbdsp_softc { struct device sc_dev; /* base device */ struct isadev sc_id; /* ISA device */ + isa_chipset_tag_t sc_ic; + bus_space_tag_t sc_iot; /* tag */ + bus_space_handle_t sc_ioh; /* handle */ void *sc_ih; /* interrupt vectoring */ int sc_iobase; /* I/O port base address */ int sc_irq; /* interrupt */ - int sc_drq; /* DMA (8-bit) */ + int sc_drq8; /* DMA (8-bit) */ int sc_drq16; /* DMA (16-bit) */ u_short sc_open; /* reference count of open calls */ @@ -88,8 +91,6 @@ struct sbdsp_softc { u_int gain[SB_NDEVS]; /* kept in SB levels: right/left each in a nibble */ - u_int encoding; /* ulaw/linear -- keep track */ - u_int out_port; /* output port */ u_int in_port; /* input port */ u_int in_filter; /* one of SB_TREBLE_EQ, SB_BASS_EQ, 0 */ @@ -112,9 +113,13 @@ struct sbdsp_softc { int dmaflags; caddr_t dmaaddr; vm_size_t dmacnt; + int dmachan; /* active DMA channel */ int sc_last_hs_size; /* last HS dma size */ - int sc_precision; /* size of samples */ + + u_int sc_encoding; /* ulaw/linear -- keep track */ + u_int sc_precision; /* size of samples */ int sc_channels; /* # of channels */ + int sc_dmadir; /* DMA direction */ #define SB_DMA_NONE 0 #define SB_DMA_IN 1 @@ -127,6 +132,9 @@ struct sbdsp_softc { #define MODEL_JAZZ16 0x80000000 }; +#define ISSB2CLASS(sc) \ + (SBVER_MAJOR((sc)->sc_model) >= 2) + #define ISSBPROCLASS(sc) \ (SBVER_MAJOR((sc)->sc_model) > 2) @@ -162,9 +170,8 @@ int sbdsp_set_out_sr __P((void *, u_long)); int sbdsp_set_out_sr_real __P((void *, u_long)); u_long sbdsp_get_out_sr __P((void *)); int sbdsp_query_encoding __P((void *, struct audio_encoding *)); -int sbdsp_set_encoding __P((void *, u_int)); +int sbdsp_set_format __P((void *, u_int, u_int)); int sbdsp_get_encoding __P((void *)); -int sbdsp_set_precision __P((void *, u_int)); int sbdsp_get_precision __P((void *)); int sbdsp_set_channels __P((void *, int)); int sbdsp_get_channels __P((void *)); @@ -186,7 +193,6 @@ int sbdsp_dma_input __P((void *, void *, int, void (*)(void *), void*)); int sbdsp_haltdma __P((void *)); int sbdsp_contdma __P((void *)); -u_int sbdsp_get_silence __P((int)); void sbdsp_compress __P((int, u_char *, int)); void sbdsp_expand __P((int, u_char *, int)); @@ -194,8 +200,8 @@ int sbdsp_reset __P((struct sbdsp_softc *)); void sbdsp_spkron __P((struct sbdsp_softc *)); void sbdsp_spkroff __P((struct sbdsp_softc *)); -int sbdsp_wdsp(int iobase, int v); -int sbdsp_rdsp(int iobase); +int sbdsp_wdsp __P((struct sbdsp_softc *, int v)); +int sbdsp_rdsp __P((struct sbdsp_softc *)); int sbdsp_intr __P((void *)); short sbversion __P((struct sbdsp_softc *)); diff --git a/sys/dev/isa/sbreg.h b/sys/dev/isa/sbreg.h index c3b72368835..b8bd566accf 100644 --- a/sys/dev/isa/sbreg.h +++ b/sys/dev/isa/sbreg.h @@ -1,4 +1,4 @@ -/* $OpenBSD: sbreg.h,v 1.2 1996/04/18 23:47:49 niklas Exp $ */ +/* $OpenBSD: sbreg.h,v 1.3 1997/07/10 23:06:39 provos Exp $ */ /* $NetBSD: sbreg.h,v 1.16 1996/03/16 04:00:14 jtk Exp $ */ /* @@ -85,6 +85,7 @@ #define SBP_SET_IRQ 0x80 /* Soft-configured irq (SB16-) */ #define SBP_SET_DRQ 0x81 /* Soft-configured drq (SB16-) */ +#define SBP_IRQ_STATUS 0x82 /* Pending IRQ status (SB16-) */ #define SBP_RECORD_SOURCE 0x0C #define SBP_STEREO 0x0E @@ -123,6 +124,8 @@ #define SBP_DSP_RSTAT 14 /* R read status */ #define SB_DSP_BUSY 0x80 #define SB_DSP_READY 0x80 +#define SBP_DSP_IRQACK8 14 /* R acknowledge DSP IRQ, 8-bit */ +#define SBP_DSP_IRQACK16 15 /* R acknowledge DSP IRQ, 16-bit */ #define SBP_CDROM_DATA 16 /* RW send cmds/recv data */ #define SBP_CDROM_STATUS 17 /* R status port */ #define SBP_CDROM_RESET 18 /* W reset register */ @@ -143,8 +146,10 @@ #define SB_DSP_DACWRITE 0x10 /* programmed I/O write to DAC */ #define SB_DSP_WDMA 0x14 /* begin 8-bit linear DMA output */ #define SB_DSP_WDMA_2 0x16 /* begin 2-bit ADPCM DMA output */ +#define SB_DSP_WDMA_LOOP 0x1C /* begin 8-bit linear DMA output loop */ #define SB_DSP_ADCREAD 0x20 /* programmed I/O read from ADC */ #define SB_DSP_RDMA 0x24 /* begin 8-bit linear DMA input */ +#define SB_DSP_RDMA_LOOP 0x2C /* begin 8-bit linear DMA input loop */ #define SB_MIDI_POLL 0x30 /* initiate a polling read for MIDI */ #define SB_MIDI_READ 0x31 /* read a MIDI byte on recv intr */ #define SB_MIDI_UART_POLL 0x34 /* enter UART mode w/ read polling */ @@ -157,8 +162,8 @@ #define SB_DSP_WDMA_4 0x74 /* begin 4-bit ADPCM DMA output */ #define SB_DSP_WDMA_2_6 0x76 /* begin 2.6-bit ADPCM DMA output */ #define SB_DSP_SILENCE 0x80 /* send a block of silence */ -#define SB_DSP_HS_OUTPUT 0x91 /* set high speed mode for wdma */ -#define SB_DSP_HS_INPUT 0x99 /* set high speed mode for rdma */ +#define SB_DSP_HS_OUTPUT 0x90 /* set high speed mode for wdma */ +#define SB_DSP_HS_INPUT 0x98 /* set high speed mode for rdma */ #define SB_DSP_RECORD_MONO 0xA0 /* set mono recording */ #define SB_DSP_RECORD_STEREO 0xA8 /* set stereo recording */ #define SB_DSP16_WDMA_16 0xB6 /* begin 16-bit linear output */ @@ -230,6 +235,8 @@ #define SBP_IRQ_VALID(irq) ((irq) == 5 || (irq) == 7 || (irq) == 9 || (irq) == 10) #define SB_IRQ_VALID(irq) ((irq) == 3 || (irq) == 5 || (irq) == 7 || (irq) == 9) +#define SB16_DRQ_VALID(chan) ((chan) == 0 || (chan) == 1 || (chan) == 3 || \ + (chan) == 5 || (chan) == 6 || (chan) == 7) #define SBP_DRQ_VALID(chan) ((chan) == 0 || (chan) == 1 || (chan) == 3) #define SB_DRQ_VALID(chan) ((chan) == 1) diff --git a/sys/dev/isa/sbvar.h b/sys/dev/isa/sbvar.h new file mode 100644 index 00000000000..82f600f29c4 --- /dev/null +++ b/sys/dev/isa/sbvar.h @@ -0,0 +1,36 @@ +/* $OpenBSD: sbvar.h,v 1.1 1997/07/10 23:06:39 provos Exp $ */ +/* $NetBSD: sbvar.h,v 1.1 1997/01/16 21:03:38 christos Exp $ */ + +/* + * Copyright (c) 1996 Christos Zoulas. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by Christos Zoulas. + * 4. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + + +struct sbdsp_softc; +int sbmatch __P((struct sbdsp_softc *)); +void sbattach __P((struct sbdsp_softc *)); diff --git a/sys/dev/isa/wss.c b/sys/dev/isa/wss.c index 593157ba477..930516b0ec1 100644 --- a/sys/dev/isa/wss.c +++ b/sys/dev/isa/wss.c @@ -1,4 +1,4 @@ -/* $OpenBSD: wss.c,v 1.13 1996/06/23 13:44:50 deraadt Exp $ */ +/* $OpenBSD: wss.c,v 1.14 1997/07/10 23:06:40 provos Exp $ */ /* $NetBSD: wss.c,v 1.13 1996/05/12 23:54:16 mycroft Exp $ */ /* @@ -131,9 +131,8 @@ struct audio_hw_if wss_hw_if = { ad1848_set_out_sr, ad1848_get_out_sr, ad1848_query_encoding, - ad1848_set_encoding, + ad1848_set_format, ad1848_get_encoding, - ad1848_set_precision, ad1848_get_precision, ad1848_set_channels, ad1848_get_channels, @@ -143,7 +142,6 @@ struct audio_hw_if wss_hw_if = { wss_set_in_port, wss_get_in_port, ad1848_commit_settings, - ad1848_get_silence, NULL, NULL, ad1848_dma_output, @@ -162,10 +160,6 @@ struct audio_hw_if wss_hw_if = { 0 }; -#ifndef NEWCONFIG -#define at_dma(flags, ptr, cc, chan) isa_dmastart(flags, ptr, cc, chan) -#endif - int wssprobe __P((struct device *, void *, void *)); void wssattach __P((struct device *, struct device *, void *)); @@ -194,23 +188,19 @@ wssprobe(parent, match, aux) static u_char dma_bits[4] = {1, 2, 0, 3}; if (!WSS_BASE_VALID(ia->ia_iobase)) { - printf("wss: configured iobase %x invalid\n", ia->ia_iobase); + DPRINTF(("wss: configured iobase %x invalid\n", ia->ia_iobase)); return 0; } if( !opti_snd_setup( OPTI_WSS, iobase, ia->ia_irq, ia->ia_drq ) ) -#ifdef DEBUG - printf("ad_detect_A: could not setup OPTi chipset.\n"); -#else - ; -#endif + DPRINTF(("ad_detect_A: could not setup OPTi chipset.\n")); - sc->sc_ad1848.sc_iobase = iobase; + sc->sc_ad1848.sc_iobase = iobase + WSS_CODEC; /* Is there an ad1848 chip at the WSS iobase ? */ if (ad1848_probe(&sc->sc_ad1848) == 0) { #if 0 - printf("ad_detect_A: no ad1848 found.\n"); + DPRINTF(("ad_detect_A: no ad1848 found.\n")); #endif return 0; } @@ -219,7 +209,7 @@ wssprobe(parent, match, aux) /* Setup WSS interrupt and DMA */ if (!WSS_DRQ_VALID(ia->ia_drq)) { - printf("wss: configured dma chan %d invalid\n", ia->ia_drq); + DPRINTF(("wss: configured dma chan %d invalid\n", ia->ia_drq)); return 0; } sc->wss_drq = ia->ia_drq; @@ -238,7 +228,7 @@ wssprobe(parent, match, aux) else #endif if (!WSS_IRQ_VALID(ia->ia_irq)) { - printf("wss: configured interrupt %d invalid\n", ia->ia_irq); + DPRINTF(("wss: configured interrupt %d invalid\n", ia->ia_irq)); return 0; } @@ -368,7 +358,7 @@ wss_get_out_port(addr) void *addr; { DPRINTF(("wss_get_out_port:\n")); - return(EINVAL); + return(WSS_DAC_LVL); } int diff --git a/sys/dev/isa/wssreg.h b/sys/dev/isa/wssreg.h index 6683c161632..63566e97349 100644 --- a/sys/dev/isa/wssreg.h +++ b/sys/dev/isa/wssreg.h @@ -37,8 +37,6 @@ * Copyright (c) 1993 Analog Devices Inc. All rights reserved */ -#define WSS_NPORT 8 - /* * Macros to detect valid hardware configuration data. */ @@ -50,12 +48,11 @@ (base) == 0x0e80 || \ (base) == 0x0f40) -/* Default WSS base */ -#define WSS_BASE_ADDRESS 0x0530 - /* WSS registers */ #define WSS_CONFIG 0x00 /* write only */ #define WSS_STATUS 0x03 /* read only */ +#define WSS_CODEC 0x04 /* ad1848 codec registers (0x04-0x07) */ +#define WSS_NPORT 8 /* WSS status register bits */ #define WSS_16SLOT 0x80 |