summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--sys/dev/audio.c404
-rw-r--r--sys/dev/audio_if.h12
-rw-r--r--sys/dev/audiovar.h7
-rw-r--r--sys/dev/isa/ad1848.c281
-rw-r--r--sys/dev/isa/ad1848var.h20
-rw-r--r--sys/dev/isa/aria.c81
-rw-r--r--sys/dev/isa/files.isa6
-rw-r--r--sys/dev/isa/gus.c130
-rw-r--r--sys/dev/isa/gusreg.h23
-rw-r--r--sys/dev/isa/pas.c11
-rw-r--r--sys/dev/isa/pss.c227
-rw-r--r--sys/dev/isa/sb.c191
-rw-r--r--sys/dev/isa/sb_isa.c133
-rw-r--r--sys/dev/isa/sbdsp.c454
-rw-r--r--sys/dev/isa/sbdspvar.h26
-rw-r--r--sys/dev/isa/sbreg.h13
-rw-r--r--sys/dev/isa/sbvar.h36
-rw-r--r--sys/dev/isa/wss.c28
-rw-r--r--sys/dev/isa/wssreg.h7
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