* Snap the sample rate when setting it, and remember only the time constant.
* Set the time constant when changing between play/record.
* Always return the actual sample rate with AUDIO_GETINFO.
This commit is contained in:
mycroft 1996-02-16 10:10:21 +00:00
parent 19f59bf3c2
commit 7847c9efee
2 changed files with 207 additions and 253 deletions

View File

@ -1,4 +1,4 @@
/* $NetBSD: sbdsp.c,v 1.15 1996/02/16 08:07:40 mycroft Exp $ */ /* $NetBSD: sbdsp.c,v 1.16 1996/02/16 10:10:21 mycroft Exp $ */
/* /*
* Copyright (c) 1991-1993 Regents of the University of California. * Copyright (c) 1991-1993 Regents of the University of California.
@ -81,20 +81,54 @@ struct {
int wmidi; int wmidi;
} sberr; } sberr;
/*
* Time constant routines follow. See SBK, section 12.
* Although they don't come out and say it (in the docs),
* the card clearly uses a 1MHz countdown timer, as the
* low-speed formula (p. 12-4) is:
* tc = 256 - 10^6 / sr
* In high-speed mode, the constant is the upper byte of a 16-bit counter,
* and a 256MHz clock is used:
* tc = 65536 - 256 * 10^ 6 / sr
* Since we can only use the upper byte of the HS TC, the two formulae
* are equivalent. (Why didn't they say so?) E.g.,
* (65536 - 256 * 10 ^ 6 / x) >> 8 = 256 - 10^6 / x
*
* The crossover point (from low- to high-speed modes) is different
* for the SBPRO and SB20. The table on p. 12-5 gives the following data:
*
* SBPRO SB20
* ----- --------
* input ls min 4 KHz 4 KHz
* input ls max 23 KHz 13 KHz
* input hs max 44.1 KHz 15 KHz
* output ls min 4 KHz 4 KHz
* output ls max 23 KHz 23 KHz
* output hs max 44.1 KHz 44.1 KHz
*/
#define SB_LS_MIN 0x06 /* 4000 Hz */
#define SB_8K 0x83 /* 8000 Hz */
#define SBPRO_ADC_LS_MAX 0xd4 /* 22727 Hz */
#define SBPRO_ADC_HS_MAX 0xea /* 45454 Hz */
#define SBCLA_ADC_LS_MAX 0xb3 /* 12987 Hz */
#define SBCLA_ADC_HS_MAX 0xbd /* 14925 Hz */
#define SB_DAC_LS_MAX 0xd4 /* 22727 Hz */
#define SB_DAC_HS_MAX 0xea /* 45454 Hz */
#ifdef AUDIO_DEBUG #ifdef AUDIO_DEBUG
void void
sb_printsc(struct sbdsp_softc *sc) sb_printsc(struct sbdsp_softc *sc)
{ {
int i; int i;
printf("open %d dmachan %d iobase %x\n", sc->sc_open, sc->sc_drq, printf("open %d dmachan %d iobase %x\n",
sc->sc_iobase); sc->sc_open, sc->sc_drq, sc->sc_iobase);
printf("hispeed %d irate %d orate %d encoding %x\n", printf("itc %d imode %d otc %d omode %d encoding %x\n",
sc->sc_adacmode, sc->sc_irate, sc->sc_orate, sc->encoding); sc->sc_itc, sc->sc_imode, sc->sc_otc, sc->sc_omode, sc->encoding);
printf("outport %d inport %d spkron %d nintr %d\n", printf("outport %d inport %d spkron %d nintr %d\n",
sc->out_port, sc->in_port, sc->spkr_state, sc->sc_interrupts); sc->out_port, sc->in_port, sc->spkr_state, sc->sc_interrupts);
printf("tc %x chans %x scintr %x arg %x\n", sc->sc_adactc, sc->sc_chans, printf("chans %x intr %x arg %x\n",
sc->sc_intr, sc->sc_arg); sc->sc_chans, sc->sc_intr, sc->sc_arg);
printf("gain: "); printf("gain: ");
for (i = 0; i < SB_NDEVS; i++) for (i = 0; i < SB_NDEVS; i++)
printf("%d ", sc->gain[i]); printf("%d ", sc->gain[i]);
@ -136,15 +170,12 @@ sbdsp_attach(sc)
/* Set defaults */ /* Set defaults */
if (ISSBPROCLASS(sc)) if (ISSBPROCLASS(sc))
sc->sc_irate = sc->sc_orate = 45454; sc->sc_itc = sc->sc_otc = SBPRO_ADC_HS_MAX;
else else
sc->sc_irate = sc->sc_orate = 14925; sc->sc_itc = sc->sc_otc = SBCLA_ADC_HS_MAX;
sc->sc_chans = 1; sc->sc_chans = 1;
sc->encoding = AUDIO_ENCODING_LINEAR; sc->encoding = AUDIO_ENCODING_LINEAR;
(void) sbdsp_set_in_sr_real(sc, sc->sc_irate);
(void) sbdsp_set_out_sr_real(sc, sc->sc_orate);
(void) sbdsp_set_in_port(sc, SB_MIC_PORT); (void) sbdsp_set_in_port(sc, SB_MIC_PORT);
(void) sbdsp_set_out_port(sc, SB_SPEAKER); (void) sbdsp_set_out_port(sc, SB_SPEAKER);
@ -166,6 +197,7 @@ sbdsp_attach(sc)
for (i = 0; i < SB_NDEVS; i++) for (i = 0; i < SB_NDEVS; i++)
sc->gain[i] = sbdsp_stereo_vol(SBP_MAXVOL, SBP_MAXVOL); sc->gain[i] = sbdsp_stereo_vol(SBP_MAXVOL, SBP_MAXVOL);
} }
printf(": dsp v%d.%02d\n", printf(": dsp v%d.%02d\n",
SBVER_MAJOR(sc->sc_model), SBVER_MINOR(sc->sc_model)); SBVER_MAJOR(sc->sc_model), SBVER_MINOR(sc->sc_model));
} }
@ -205,25 +237,7 @@ sbdsp_set_in_sr(addr, sr)
{ {
register struct sbdsp_softc *sc = addr; register struct sbdsp_softc *sc = addr;
sc->sc_irate = sr; return (sbdsp_srtotc(sc, sr, SB_INPUT_RATE, &sc->sc_itc, &sc->sc_imode));
return 0;
}
int
sbdsp_set_in_sr_real(addr, sr)
void *addr;
u_long sr;
{
register struct sbdsp_softc *sc = addr;
int rval;
if (rval = sbdsp_set_sr(sc, &sr, SB_INPUT_RATE))
return rval;
sc->sc_irate = sr;
if (sc->sc_dmadir == SBP_DMA_IN)
sc->sc_dmadir = SBP_DMA_NONE; /* do it again on next DMA in */
return 0;
} }
u_long u_long
@ -232,7 +246,7 @@ sbdsp_get_in_sr(addr)
{ {
register struct sbdsp_softc *sc = addr; register struct sbdsp_softc *sc = addr;
return(sc->sc_irate); return (sbdsp_tctosr(sc, sc->sc_itc));
} }
int int
@ -242,24 +256,7 @@ sbdsp_set_out_sr(addr, sr)
{ {
register struct sbdsp_softc *sc = addr; register struct sbdsp_softc *sc = addr;
sc->sc_orate = sr; return (sbdsp_srtotc(sc, sr, SB_OUTPUT_RATE, &sc->sc_otc, &sc->sc_omode));
return(0);
}
int
sbdsp_set_out_sr_real(addr, sr)
void *addr;
u_long sr;
{
register struct sbdsp_softc *sc = addr;
int rval;
if (rval = sbdsp_set_sr(sc, &sr, SB_OUTPUT_RATE))
return rval;
sc->sc_orate = sr;
if (sc->sc_dmadir == SBP_DMA_OUT)
sc->sc_dmadir = SBP_DMA_NONE; /* do it again on next DMA out */
return 0;
} }
u_long u_long
@ -268,7 +265,7 @@ sbdsp_get_out_sr(addr)
{ {
register struct sbdsp_softc *sc = addr; register struct sbdsp_softc *sc = addr;
return(sc->sc_orate); return (sbdsp_tctosr(sc, sc->sc_otc));
} }
int int
@ -289,7 +286,6 @@ sbdsp_query_encoding(addr, fp)
break; break;
default: default:
return (EINVAL); return (EINVAL);
/*NOTREACHED*/
} }
return (0); return (0);
} }
@ -347,26 +343,27 @@ sbdsp_set_channels(addr, chans)
int chans; int chans;
{ {
register struct sbdsp_softc *sc = addr; register struct sbdsp_softc *sc = addr;
int rval;
if (ISSBPROCLASS(sc)) { if (ISSBPROCLASS(sc)) {
if (chans != 1 && chans != 2) if (chans != 1 && chans != 2)
return (EINVAL); return (EINVAL);
sc->sc_chans = chans; sc->sc_chans = chans;
#if 0
if (rval = sbdsp_set_in_sr_real(addr, sc->sc_irate)) if (rval = sbdsp_set_in_sr_real(addr, sc->sc_irate))
return rval; return rval;
#endif
sbdsp_mix_write(sc, SBP_STEREO, sbdsp_mix_write(sc, SBP_STEREO,
(sbdsp_mix_read(sc, SBP_STEREO) & ~SBP_PLAYMODE_MASK) | (sbdsp_mix_read(sc, SBP_STEREO) & ~SBP_PLAYMODE_MASK) |
(chans == 2 ? SBP_PLAYMODE_STEREO : SBP_PLAYMODE_MONO)); (chans == 2 ? SBP_PLAYMODE_STEREO : SBP_PLAYMODE_MONO));
/* recording channels needs to be done right when we start /* recording channels needs to be done right when we start
DMA recording. Just record number of channels for now DMA recording. Just record number of channels for now
and set stereo when ready. */ and set stereo when ready. */
} } else {
else {
if (chans != 1) if (chans != 1)
return (EINVAL); return (EINVAL);
sc->sc_chans = 1; sc->sc_chans = chans;
} }
return (0); return (0);
@ -381,16 +378,12 @@ sbdsp_get_channels(addr)
#if 0 #if 0
/* recording stereo may frob the mixer output */ /* recording stereo may frob the mixer output */
if (ISSBPROCLASS(sc)) { if (ISSBPROCLASS(sc)) {
if ((sbdsp_mix_read(sc, SBP_STEREO) & SBP_PLAYMODE_MASK) == SBP_PLAYMODE_STEREO) { if ((sbdsp_mix_read(sc, SBP_STEREO) & SBP_PLAYMODE_MASK) == SBP_PLAYMODE_STEREO)
sc->sc_chans = 2; sc->sc_chans = 2;
} else
else {
sc->sc_chans = 1; sc->sc_chans = 1;
} } else
}
else {
sc->sc_chans = 1; sc->sc_chans = 1;
}
#endif #endif
return (sc->sc_chans); return (sc->sc_chans);
@ -444,10 +437,8 @@ sbdsp_set_in_port(addr, port)
case SB_FM_PORT: case SB_FM_PORT:
default: default:
return (EINVAL); return (EINVAL);
/*NOTREACHED*/
} }
} } else {
else {
switch (port) { switch (port) {
case SB_MIC_PORT: case SB_MIC_PORT:
sbport = SBP_FROM_MIC; sbport = SBP_FROM_MIC;
@ -455,7 +446,6 @@ sbdsp_set_in_port(addr, port)
break; break;
default: default:
return (EINVAL); return (EINVAL);
/*NOTREACHED*/
} }
} }
@ -513,11 +503,12 @@ sbdsp_round_blocksize(addr, blk)
sc->sc_last_hs_size = 0; sc->sc_last_hs_size = 0;
/* Higher speeds need bigger blocks to avoid popping and silence gaps. */ /* Higher speeds need bigger blocks to avoid popping and silence gaps. */
if ((sc->sc_orate > 8000 || sc->sc_irate > 8000) && if ((sc->sc_otc > SB_8K || sc->sc_itc > SB_8K) &&
(blk > NBPG/2 || blk < NBPG/4)) (blk > NBPG/2 || blk < NBPG/4))
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, though. */
if (blk > NBPG) blk = NBPG; if (blk > NBPG)
blk = NBPG;
if (sc->sc_chans == 2) if (sc->sc_chans == 2)
return (blk & ~1); /* must be even to preserve stereo separation */ return (blk & ~1); /* must be even to preserve stereo separation */
else else
@ -528,15 +519,18 @@ int
sbdsp_commit_settings(addr) sbdsp_commit_settings(addr)
void *addr; void *addr;
{ {
register struct sbdsp_softc *sc = addr;
/* due to potentially unfortunate ordering in the above layers, /* due to potentially unfortunate ordering in the above layers,
re-do a few sets which may be important--input gains re-do a few sets which may be important--input gains
(adjust the proper channels), number of input channels (hit the (adjust the proper channels), number of input channels (hit the
record rate and set mode) */ record rate and set mode) */
register struct sbdsp_softc *sc = addr; /*
* XXX
sbdsp_set_out_sr_real(addr, sc->sc_orate); * Should wait for chip to be idle.
sbdsp_set_in_sr_real(addr, sc->sc_irate); */
sc->sc_dmadir = SB_DMA_NONE;
return 0; return 0;
} }
@ -604,9 +598,9 @@ sbdsp_reset(sc)
register int iobase = sc->sc_iobase; register int iobase = sc->sc_iobase;
sc->sc_intr = 0; sc->sc_intr = 0;
if (sc->sc_dmadir != SBP_DMA_NONE) { if (sc->sc_dmadir != SB_DMA_NONE) {
isa_dmaabort(sc->sc_drq); isa_dmaabort(sc->sc_drq);
sc->sc_dmadir = SBP_DMA_NONE; sc->sc_dmadir = SB_DMA_NONE;
} }
sc->sc_last_hs_size = 0; sc->sc_last_hs_size = 0;
@ -768,39 +762,6 @@ sbdsp_contdma(addr)
return(0); return(0);
} }
/*
* Time constant routines follow. See SBK, section 12.
* Although they don't come out and say it (in the docs),
* the card clearly uses a 1MHz countdown timer, as the
* low-speed formula (p. 12-4) is:
* tc = 256 - 10^6 / sr
* In high-speed mode, the constant is the upper byte of a 16-bit counter,
* and a 256MHz clock is used:
* tc = 65536 - 256 * 10^ 6 / sr
* Since we can only use the upper byte of the HS TC, the two formulae
* are equivalent. (Why didn't they say so?) E.g.,
* (65536 - 256 * 10 ^ 6 / x) >> 8 = 256 - 10^6 / x
*
* The crossover point (from low- to high-speed modes) is different
* for the SBPRO and SB20. The table on p. 12-5 gives the following data:
*
* SBPRO SB20
* ----- --------
* input ls min 4 KHz 4 KHz
* input ls max 23 KHz 13 KHz
* input hs max 44.1 KHz 15 KHz
* output ls min 4 KHz 4 KHz
* output ls max 23 KHz 23 KHz
* output hs max 44.1 KHz 44.1 KHz
*/
#define SB_LS_MIN 0x06 /* 4000 Hz */
#define SBPRO_ADC_LS_MAX 0xd4 /* 22727 Hz */
#define SBPRO_ADC_HS_MAX 0xea /* 45454 Hz */
#define SBCLA_ADC_LS_MAX 0xb3 /* 12987 Hz */
#define SBCLA_ADC_HS_MAX 0xbd /* 14925 Hz */
#define SB_DAC_LS_MAX 0xd4 /* 22727 Hz */
#define SB_DAC_HS_MAX 0xea /* 45454 Hz */
/* /*
* Convert a linear sampling rate into the DAC time constant. * Convert a linear sampling rate into the DAC time constant.
* Set *mode to indicate the high/low-speed DMA operation. * Set *mode to indicate the high/low-speed DMA operation.
@ -810,53 +771,60 @@ sbdsp_contdma(addr)
* so isdac indicates output, and !isdac indicates input. * so isdac indicates output, and !isdac indicates input.
*/ */
int int
sbdsp_srtotc(sc, sr, mode, isdac) sbdsp_srtotc(sc, sr, isdac, tcp, modep)
register struct sbdsp_softc *sc; register struct sbdsp_softc *sc;
int sr; int sr;
int *mode;
int isdac; int isdac;
int *tcp, *modep;
{ {
int adc_ls_max, adc_hs_max; int tc, mode;
register int tc;
if (sr == 0) { if (sr == 0) {
*mode = SB_ADAC_LS; tc = SB_LS_MIN;
return SB_LS_MIN; mode = SB_ADAC_LS;
goto out;
} }
tc = 256 - 1000000 / sr;
tc = 256 - (1000000 / sr);
if (tc < SB_LS_MIN) {
tc = SB_LS_MIN;
mode = SB_ADAC_LS;
goto out;
} else if (isdac) {
if (tc <= SB_DAC_LS_MAX)
mode = SB_ADAC_LS;
else {
mode = SB_ADAC_HS;
if (tc > SB_DAC_HS_MAX)
tc = SB_DAC_HS_MAX;
}
} else {
int adc_ls_max, adc_hs_max;
/* XXX use better rounding--compare distance to nearest tc on both /* XXX use better rounding--compare distance to nearest tc on both
sides of requested speed */ sides of requested speed */
if (ISSBPROCLASS(sc)) { if (ISSBPROCLASS(sc)) {
adc_ls_max = SBPRO_ADC_LS_MAX; adc_ls_max = SBPRO_ADC_LS_MAX;
adc_hs_max = SBPRO_ADC_HS_MAX; adc_hs_max = SBPRO_ADC_HS_MAX;
} } else {
else {
adc_ls_max = SBCLA_ADC_LS_MAX; adc_ls_max = SBCLA_ADC_LS_MAX;
adc_hs_max = SBCLA_ADC_HS_MAX; adc_hs_max = SBCLA_ADC_HS_MAX;
} }
if (tc < SB_LS_MIN) {
tc = SB_LS_MIN;
*mode = SB_ADAC_LS;
} else if (isdac) {
if (tc <= SB_DAC_LS_MAX)
*mode = SB_ADAC_LS;
else {
*mode = SB_ADAC_HS;
if (tc > SB_DAC_HS_MAX)
tc = SB_DAC_HS_MAX;
}
} else {
if (tc <= adc_ls_max) if (tc <= adc_ls_max)
*mode = SB_ADAC_LS; mode = SB_ADAC_LS;
else { else {
*mode = SB_ADAC_HS; mode = SB_ADAC_HS;
if (tc > adc_hs_max) if (tc > adc_hs_max)
tc = adc_hs_max; tc = adc_hs_max;
} }
} }
return tc;
out:
*tcp = tc;
*modep = mode;
return (0);
} }
/* /*
@ -882,47 +850,27 @@ sbdsp_tctosr(sc, tc)
} }
int int
sbdsp_set_sr(sc, srp, isdac) sbdsp_set_tc(sc, tc)
register struct sbdsp_softc *sc; register struct sbdsp_softc *sc;
u_long *srp; int tc;
int isdac;
{ {
register int tc;
int mode;
int sr = *srp;
register int iobase; register int iobase;
/* /*
* A SBPro in stereo mode uses time constants at double the * A SBPro in stereo mode uses time constants at double the
* actual rate. * actual rate.
*/ */
if (ISSBPRO(sc) && sc->sc_chans == 2) { if (ISSBPRO(sc) && sc->sc_chans == 2)
if (sr > 22727) tc = 256 - ((256 - tc) / 2);
sr = 22727; /* Can't bounce it...order of
operations may yield bogus
sr here. */
sr *= 2;
}
else if (!ISSBPROCLASS(sc) && sc->sc_chans != 1)
return EINVAL;
tc = sbdsp_srtotc(sc, sr, &mode, isdac); DPRINTF(("sbdsp_set_tc: sc=%p tc=%d\n", sc, tc));
DPRINTF(("sbdsp_set_sr: sc=0x%x sr=%d mode=0x%x\n", sc, sr, mode));
iobase = sc->sc_iobase; iobase = sc->sc_iobase;
if (sbdsp_wdsp(iobase, SB_DSP_TIMECONST) < 0 || if (sbdsp_wdsp(iobase, SB_DSP_TIMECONST) < 0 ||
sbdsp_wdsp(iobase, tc) < 0) sbdsp_wdsp(iobase, tc) < 0)
return EIO; return (EIO);
sr = sbdsp_tctosr(sc, tc); return (0);
if (ISSBPRO(sc) && sc->sc_chans == 2)
*srp = sr / 2;
else
*srp = sr;
sc->sc_adacmode = mode;
sc->sc_adactc = tc;
return 0;
} }
int int
@ -946,22 +894,24 @@ sbdsp_dma_input(addr, p, cc, intr, arg)
} }
iobase = sc->sc_iobase; iobase = sc->sc_iobase;
if (ISSBPROCLASS(sc) && sc->sc_dmadir != SBP_DMA_IN) { if (sc->sc_dmadir != SB_DMA_IN) {
if (ISSBPROCLASS(sc)) {
if (sc->sc_chans == 2) { if (sc->sc_chans == 2) {
if (sbdsp_wdsp(iobase, SB_DSP_RECORD_STEREO) < 0) if (sbdsp_wdsp(iobase, SB_DSP_RECORD_STEREO) < 0)
goto badmode; goto badmode;
sbdsp_mix_write(sc, SBP_INFILTER, sbdsp_mix_write(sc, SBP_INFILTER,
sbdsp_mix_read(sc, SBP_INFILTER) | SBP_FILTER_OFF); sbdsp_mix_read(sc, SBP_INFILTER) | SBP_FILTER_OFF);
} } else {
else {
if (sbdsp_wdsp(iobase, SB_DSP_RECORD_MONO) < 0) if (sbdsp_wdsp(iobase, SB_DSP_RECORD_MONO) < 0)
goto badmode; goto badmode;
sbdsp_mix_write(sc, SBP_INFILTER, sbdsp_mix_write(sc, SBP_INFILTER, sc->sc_itc > SB_8K ?
sc->sc_irate <= 8000 ? sbdsp_mix_read(sc, SBP_INFILTER) | SBP_FILTER_OFF :
sbdsp_mix_read(sc, SBP_INFILTER) & ~SBP_FILTER_MASK : sbdsp_mix_read(sc, SBP_INFILTER) & ~SBP_FILTER_MASK);
sbdsp_mix_read(sc, SBP_INFILTER) | SBP_FILTER_OFF);
} }
sc->sc_dmadir = SBP_DMA_IN; }
sbdsp_set_tc(sc, sc->sc_itc);
sc->sc_dmadir = SB_DMA_IN;
} }
isa_dmastart(B_READ, p, cc, sc->sc_drq); isa_dmastart(B_READ, p, cc, sc->sc_drq);
@ -971,7 +921,7 @@ sbdsp_dma_input(addr, p, cc, intr, arg)
sc->dmaaddr = p; sc->dmaaddr = p;
sc->dmacnt = --cc; /* DMA controller is strange...? */ sc->dmacnt = --cc; /* DMA controller is strange...? */
if (sc->sc_adacmode == SB_ADAC_LS) { if (sc->sc_imode == SB_ADAC_LS) {
if (sbdsp_wdsp(iobase, SB_DSP_RDMA) < 0 || if (sbdsp_wdsp(iobase, SB_DSP_RDMA) < 0 ||
sbdsp_wdsp(iobase, cc) < 0 || sbdsp_wdsp(iobase, cc) < 0 ||
sbdsp_wdsp(iobase, cc >> 8) < 0) { sbdsp_wdsp(iobase, cc >> 8) < 0) {
@ -1027,14 +977,17 @@ sbdsp_dma_output(addr, p, cc, intr, arg)
} }
iobase = sc->sc_iobase; iobase = sc->sc_iobase;
if (ISSBPROCLASS(sc) && sc->sc_dmadir != SBP_DMA_OUT) { if (sc->sc_dmadir != SB_DMA_OUT) {
if (ISSBPROCLASS(sc)) {
/* make sure we re-set stereo mixer bit when we start /* make sure we re-set stereo mixer bit when we start
output. */ output. */
sbdsp_mix_write(sc, SBP_STEREO, sbdsp_mix_write(sc, SBP_STEREO,
(sbdsp_mix_read(sc, SBP_STEREO) & ~SBP_PLAYMODE_MASK) | (sbdsp_mix_read(sc, SBP_STEREO) & ~SBP_PLAYMODE_MASK) |
(sc->sc_chans == 2 ? (sc->sc_chans == 2 ? SBP_PLAYMODE_STEREO : SBP_PLAYMODE_MONO));
SBP_PLAYMODE_STEREO : SBP_PLAYMODE_MONO)); }
sc->sc_dmadir = SBP_DMA_OUT;
sbdsp_set_tc(sc, sc->sc_otc);
sc->sc_dmadir = SB_DMA_OUT;
} }
isa_dmastart(B_WRITE, p, cc, sc->sc_drq); isa_dmastart(B_WRITE, p, cc, sc->sc_drq);
@ -1044,7 +997,7 @@ sbdsp_dma_output(addr, p, cc, intr, arg)
sc->dmaaddr = p; sc->dmaaddr = p;
sc->dmacnt = --cc; /* a vagary of how DMA works, apparently. */ sc->dmacnt = --cc; /* a vagary of how DMA works, apparently. */
if (sc->sc_adacmode == SB_ADAC_LS) { if (sc->sc_omode == SB_ADAC_LS) {
if (sbdsp_wdsp(iobase, SB_DSP_WDMA) < 0 || if (sbdsp_wdsp(iobase, SB_DSP_WDMA) < 0 ||
sbdsp_wdsp(iobase, cc) < 0 || sbdsp_wdsp(iobase, cc) < 0 ||
sbdsp_wdsp(iobase, cc >> 8) < 0) { sbdsp_wdsp(iobase, cc >> 8) < 0) {

View File

@ -1,4 +1,4 @@
/* $NetBSD: sbdspvar.h,v 1.8 1996/02/16 08:07:46 mycroft Exp $ */ /* $NetBSD: sbdspvar.h,v 1.9 1996/02/16 10:10:23 mycroft Exp $ */
/* /*
* Copyright (c) 1991-1993 Regents of the University of California. * Copyright (c) 1991-1993 Regents of the University of California.
@ -80,10 +80,6 @@ struct sbdsp_softc {
int sc_drq; /* DMA */ int sc_drq; /* DMA */
u_short sc_open; /* reference count of open calls */ u_short sc_open; /* reference count of open calls */
u_short sc_adacmode; /* low/high speed mode indicator */
u_long sc_irate; /* Sample rate for input */
u_long sc_orate; /* ...and output */
u_int gain[SB_NDEVS]; /* kept in SB levels: right/left each u_int gain[SB_NDEVS]; /* kept in SB levels: right/left each
in a nibble */ in a nibble */
@ -95,9 +91,14 @@ struct sbdsp_softc {
u_int spkr_state; /* non-null is on */ u_int spkr_state; /* non-null is on */
int sc_itc; /* Sample rate for input */
int sc_otc; /* ...and output */
int sc_imode;
int sc_omode;
#define SB_ADAC_LS 0 #define SB_ADAC_LS 0
#define SB_ADAC_HS 1 #define SB_ADAC_HS 1
u_short sc_adactc; /* current adac time constant */
u_long sc_interrupts; /* number of interrupts taken */ u_long sc_interrupts; /* number of interrupts taken */
void (*sc_intr)(void*); /* dma completion intr handler */ void (*sc_intr)(void*); /* dma completion intr handler */
void (*sc_mintr)(void*, int);/* midi input intr handler */ void (*sc_mintr)(void*, int);/* midi input intr handler */
@ -109,9 +110,9 @@ struct sbdsp_softc {
int sc_last_hs_size; /* last HS dma size */ int sc_last_hs_size; /* last HS dma size */
int sc_chans; /* # of channels */ int sc_chans; /* # of channels */
int sc_dmadir; /* DMA direction */ int sc_dmadir; /* DMA direction */
#define SBP_DMA_NONE 0 #define SB_DMA_NONE 0
#define SBP_DMA_IN 1 #define SB_DMA_IN 1
#define SBP_DMA_OUT 2 #define SB_DMA_OUT 2
u_int sc_model; /* DSP model */ u_int sc_model; /* DSP model */
#define SBVER_MAJOR(v) ((v)>>8) #define SBVER_MAJOR(v) ((v)>>8)