diff --git a/sys/dev/ata/wd.c b/sys/dev/ata/wd.c index 9e296c91ee93..da2ed01e4d96 100644 --- a/sys/dev/ata/wd.c +++ b/sys/dev/ata/wd.c @@ -1,4 +1,4 @@ -/* $NetBSD: wd.c,v 1.145 1996/01/08 21:21:56 mycroft Exp $ */ +/* $NetBSD: wd.c,v 1.146 1996/03/01 04:08:51 mycroft Exp $ */ /* * Copyright (c) 1994, 1995 Charles M. Hannum. All rights reserved. @@ -53,6 +53,7 @@ #include #include +#include #include #define WAITTIME (4 * hz) /* time to wait for a completion */ @@ -661,7 +662,8 @@ loop: WDCC_READDMA : WDCC_WRITEDMA; /* Start the DMA channel and bounce the buffer if necessary. */ - isa_dmastart(bp->b_flags & B_READ, + isa_dmastart( + bp->b_flags & B_READ ? DMAMODE_READ : DMAMODE_WRITE, bp->b_data + wd->sc_skip, wd->sc_nbytes, wdc->sc_drq); break; @@ -765,8 +767,8 @@ wdcintr(arg) /* Turn off the DMA channel and unbounce the buffer. */ if (wd->sc_mode == WDM_DMA) - isa_dmadone(bp->b_flags & B_READ, bp->b_data + wd->sc_skip, - wd->sc_nbytes, wdc->sc_drq); + isa_dmadone(bp->b_flags & B_READ ? DMAMODE_READ : DMAMODE_WRITE, + bp->b_data + wd->sc_skip, wd->sc_nbytes, wdc->sc_drq); /* Have we an error? */ if (wdc->sc_status & WDCS_ERR) { diff --git a/sys/dev/isa/ad1848.c b/sys/dev/isa/ad1848.c index a976f48371a6..1732df537f33 100644 --- a/sys/dev/isa/ad1848.c +++ b/sys/dev/isa/ad1848.c @@ -1,4 +1,4 @@ -/* $NetBSD: ad1848.c,v 1.8 1996/02/05 21:32:26 scottr Exp $ */ +/* $NetBSD: ad1848.c,v 1.9 1996/03/01 04:08:24 mycroft Exp $ */ /* * Copyright (c) 1994 John Brezak @@ -276,7 +276,7 @@ ad1848_forceintr(sc) * it is needed (and you pay the latency). Also, you might * never need the buffer anyway.) */ - isa_dmastart(B_READ, &dmabuf, 1, sc->sc_drq); + isa_dmastart(DMAMODE_READ, &dmabuf, 1, sc->sc_drq); ad_write(sc, SP_LOWER_BASE_COUNT, 0); ad_write(sc, SP_UPPER_BASE_COUNT, 0); @@ -1520,10 +1520,10 @@ ad1848_dma_input(addr, p, cc, intr, arg) sc->sc_locked = 1; sc->sc_intr = intr; sc->sc_arg = arg; - sc->sc_dma_flags = B_READ; + sc->sc_dma_flags = DMAMODE_READ; sc->sc_dma_bp = p; sc->sc_dma_cnt = cc; - isa_dmastart(B_READ, p, cc, sc->sc_recdrq); + isa_dmastart(DMAMODE_READ, p, cc, sc->sc_recdrq); if (sc->precision == 16) cc >>= 1; @@ -1575,10 +1575,10 @@ ad1848_dma_output(addr, p, cc, intr, arg) sc->sc_locked = 1; sc->sc_intr = intr; sc->sc_arg = arg; - sc->sc_dma_flags = B_WRITE; + sc->sc_dma_flags = DMAMODE_WRITE; sc->sc_dma_bp = p; sc->sc_dma_cnt = cc; - isa_dmastart(B_WRITE, p, cc, sc->sc_drq); + isa_dmastart(DMAMODE_WRITE, p, cc, sc->sc_drq); if (sc->precision == 16) cc >>= 1; @@ -1621,7 +1621,7 @@ ad1848_intr(arg) if (sc->sc_intr && (status & INTERRUPT_STATUS)) { /* ACK DMA read because it may be in a bounce buffer */ /* XXX Do write to mask DMA ? */ - if (sc->sc_dma_flags & B_READ) + if (sc->sc_dma_flags & DMAMODE_READ) isa_dmadone(sc->sc_dma_flags, sc->sc_dma_bp, sc->sc_dma_cnt - 1, sc->sc_recdrq); (*sc->sc_intr)(sc->sc_arg); retval = 1; diff --git a/sys/dev/isa/gus.c b/sys/dev/isa/gus.c index 4f897019c59f..7f0602cdc3e4 100644 --- a/sys/dev/isa/gus.c +++ b/sys/dev/isa/gus.c @@ -1,4 +1,4 @@ -/* $NetBSD: gus.c,v 1.9 1996/02/17 04:49:50 jtk Exp $ */ +/* $NetBSD: gus.c,v 1.10 1996/03/01 04:08:31 mycroft Exp $ */ /*- * Copyright (c) 1996 The NetBSD Foundation, Inc. @@ -1399,7 +1399,7 @@ gus_dmaout_dointr(sc) register int port = sc->sc_iobase; /* sc->sc_dmaoutcnt - 1 because DMA controller counts from zero?. */ - isa_dmadone(B_WRITE, + isa_dmadone(DMAMODE_WRITE, sc->sc_dmaoutaddr, sc->sc_dmaoutcnt - 1, sc->sc_drq); @@ -1909,7 +1909,7 @@ gusdmaout(sc, flags, gusaddr, buffaddr, length) sc->sc_dmaoutaddr = (u_char *) buffaddr; sc->sc_dmaoutcnt = length; - isa_dmastart(B_WRITE, buffaddr, length, sc->sc_drq); + isa_dmastart(DMAMODE_WRITE, buffaddr, length, sc->sc_drq); /* * Set up DMA address - use the upper 16 bits ONLY @@ -3253,7 +3253,7 @@ gus_dma_input(addr, buf, size, callback, arg) dmac |= GUSMASK_SAMPLE_INVBIT; if (sc->sc_channels == 2) dmac |= GUSMASK_SAMPLE_STEREO; - isa_dmastart(B_READ, (caddr_t) buf, size, sc->sc_recdrq); + isa_dmastart(DMAMODE_READ, (caddr_t) buf, size, sc->sc_recdrq); DMAPRINTF(("gus_dma_input isa_dmastarted\n")); sc->sc_flags |= GUS_DMAIN_ACTIVE; @@ -3280,7 +3280,7 @@ gus_dmain_intr(sc) DMAPRINTF(("gus_dmain_intr called\n")); if (sc->sc_dmainintr) { - isa_dmadone(B_READ, sc->sc_dmainaddr, sc->sc_dmaincnt - 1, + isa_dmadone(DMAMODE_READ, sc->sc_dmainaddr, sc->sc_dmaincnt - 1, sc->sc_recdrq); callback = sc->sc_dmainintr; arg = sc->sc_inarg; diff --git a/sys/dev/isa/isadma.c b/sys/dev/isa/isadma.c index 195310cff15e..352ea35f494d 100644 --- a/sys/dev/isa/isadma.c +++ b/sys/dev/isa/isadma.c @@ -1,4 +1,4 @@ -/* $NetBSD: isadma.c,v 1.14 1996/02/22 06:21:48 mycroft Exp $ */ +/* $NetBSD: isadma.c,v 1.15 1996/03/01 04:08:48 mycroft Exp $ */ #include #include @@ -24,8 +24,16 @@ static char bounced[8]; /* XXX */ static u_int8_t dma_finished; /* high byte of address is stored in this port for i-th dma channel */ -static int dmapageport[8] = - { 0x87, 0x83, 0x81, 0x82, 0x8f, 0x8b, 0x89, 0x8a }; +static int dmapageport[8] = { + 0x87, 0x83, 0x81, 0x82, 0x8f, 0x8b, 0x89, 0x8a +}; + +static u_int8_t dmamode[4] = { + DMA37MD_WRITE | DMA37MD_SINGLE, + DMA37MD_READ | DMA37MD_SINGLE, + DMA37MD_WRITE | DMA37MD_LOOP, + DMA37MD_READ | DMA37MD_LOOP +}; /* * isa_dmacascade(): program 8237 DMA controller channel to accept @@ -43,11 +51,13 @@ isa_dmacascade(chan) /* set dma channel mode, and set dma channel mode */ if ((chan & 4) == 0) { - outb(DMA1_MODE, DMA37MD_CASCADE | chan); + outb(DMA1_MODE, chan | DMA37MD_CASCADE); outb(DMA1_SMSK, chan); } else { - outb(DMA2_MODE, DMA37MD_CASCADE | (chan & 3)); - outb(DMA2_SMSK, chan & 3); + chan &= 3; + + outb(DMA2_MODE, chan | DMA37MD_CASCADE); + outb(DMA2_SMSK, chan); } } @@ -82,7 +92,7 @@ isa_dmastart(flags, addr, nbytes, chan) newaddr = dma_bounce[chan]; *(int *) newaddr = 0; /* XXX */ /* copy bounce buffer on write */ - if ((flags & B_READ) == 0) + if ((flags & DMAMODE_READ) == 0) bcopy(addr, newaddr, nbytes); addr = newaddr; } @@ -98,17 +108,17 @@ isa_dmastart(flags, addr, nbytes, chan) * byte mode channels. */ /* set dma channel mode, and reset address ff */ - if (flags & B_READ) - outb(DMA1_MODE, chan | DMA37MD_SINGLE | DMA37MD_WRITE); + if (flags & DMAMODE_READ) + outb(DMA1_MODE, chan | dmamode[flags]); else - outb(DMA1_MODE, chan | DMA37MD_SINGLE | DMA37MD_READ); + outb(DMA1_MODE, chan | dmamode[flags]); outb(DMA1_FFC, 0); /* send start address */ - waport = DMA1_CHN(chan); + waport = DMA1_CHN(chan); + outb(dmapageport[chan], phys>>16); outb(waport, phys); outb(waport, phys>>8); - outb(dmapageport[chan], phys>>16); /* send count */ outb(waport + 1, --nbytes); @@ -117,22 +127,25 @@ isa_dmastart(flags, addr, nbytes, chan) /* unmask channel */ outb(DMA1_SMSK, chan | DMA37SM_CLEAR); } else { + chan &= 3; + /* * Program one of DMA channels 4..7. These are * word mode channels. */ /* set dma channel mode, and reset address ff */ - if (flags & B_READ) - outb(DMA2_MODE, (chan & 3) | DMA37MD_SINGLE | DMA37MD_WRITE); + if (flags & DMAMODE_READ) + outb(DMA2_MODE, chan | dmamode[flags]); else - outb(DMA2_MODE, (chan & 3) | DMA37MD_SINGLE | DMA37MD_READ); + outb(DMA2_MODE, chan | dmamode[flags]); outb(DMA2_FFC, 0); /* send start address */ - waport = DMA2_CHN(chan & 3); - outb(waport, phys>>1); - outb(waport, phys>>9); + waport = DMA2_CHN(chan); outb(dmapageport[chan], phys>>16); + phys >>= 1; + outb(waport, phys); + outb(waport, phys>>8); /* send count */ nbytes >>= 1; @@ -140,7 +153,7 @@ isa_dmastart(flags, addr, nbytes, chan) outb(waport + 2, nbytes>>8); /* unmask channel */ - outb(DMA2_SMSK, (chan & 3) | DMA37SM_CLEAR); + outb(DMA2_SMSK, chan | DMA37SM_CLEAR); } } diff --git a/sys/dev/isa/isadmavar.h b/sys/dev/isa/isadmavar.h index f36fdec8bb34..c77bec6abc68 100644 --- a/sys/dev/isa/isadmavar.h +++ b/sys/dev/isa/isadmavar.h @@ -1,4 +1,8 @@ -/* $NetBSD: isadmavar.h,v 1.3 1996/02/20 04:17:06 mycroft Exp $ */ +/* $NetBSD: isadmavar.h,v 1.4 1996/03/01 04:08:46 mycroft Exp $ */ + +#define DMAMODE_WRITE 0 +#define DMAMODE_READ 1 +#define DMAMODE_LOOP 2 void isa_dmacascade __P((int)); void isa_dmastart __P((int, caddr_t, vm_size_t, int)); diff --git a/sys/dev/isa/pas.c b/sys/dev/isa/pas.c index dce1973590b2..82f0c6b3ec6c 100644 --- a/sys/dev/isa/pas.c +++ b/sys/dev/isa/pas.c @@ -1,4 +1,4 @@ -/* $NetBSD: pas.c,v 1.12 1996/02/16 08:18:34 mycroft Exp $ */ +/* $NetBSD: pas.c,v 1.13 1996/03/01 04:08:43 mycroft Exp $ */ /* * Copyright (c) 1991-1993 Regents of the University of California. @@ -407,7 +407,7 @@ pasforceintr(aux) * it is needed (and you pay the latency). Also, you might * never need the buffer anyway.) */ - at_dma(1, &dmabuf, 1, ia->ia_drq); + at_dma(DMAMODE_READ, &dmabuf, 1, ia->ia_drq); if (pas_wdsp(iobase, SB_DSP_RDMA) == 0) { (void)pas_wdsp(iobase, 0); (void)pas_wdsp(iobase, 0); diff --git a/sys/dev/isa/sb.c b/sys/dev/isa/sb.c index ae15a94748b9..7c9d4d064e7f 100644 --- a/sys/dev/isa/sb.c +++ b/sys/dev/isa/sb.c @@ -1,4 +1,4 @@ -/* $NetBSD: sb.c,v 1.30 1996/02/16 08:18:32 mycroft Exp $ */ +/* $NetBSD: sb.c,v 1.31 1996/03/01 04:08:45 mycroft Exp $ */ /* * Copyright (c) 1991-1993 Regents of the University of California. @@ -247,7 +247,7 @@ sbforceintr(aux) * it is needed (and you pay the latency). Also, you might * never need the buffer anyway.) */ - at_dma(B_READ, &dmabuf, 1, ia->ia_drq); + 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); diff --git a/sys/dev/isa/sbdsp.c b/sys/dev/isa/sbdsp.c index 3f5a2739ca63..3462a8ca2e8c 100644 --- a/sys/dev/isa/sbdsp.c +++ b/sys/dev/isa/sbdsp.c @@ -1,4 +1,4 @@ -/* $NetBSD: sbdsp.c,v 1.22 1996/02/20 11:48:50 mycroft Exp $ */ +/* $NetBSD: sbdsp.c,v 1.23 1996/03/01 04:08:38 mycroft Exp $ */ /* * Copyright (c) 1991-1993 Regents of the University of California. @@ -123,12 +123,13 @@ sb_printsc(struct sbdsp_softc *sc) printf("open %d dmachan %d iobase %x\n", sc->sc_open, sc->sc_drq, sc->sc_iobase); - printf("itc %d imode %d otc %d omode %d encoding %x\n", - sc->sc_itc, sc->sc_imode, sc->sc_otc, sc->sc_omode, sc->encoding); + 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); printf("outport %d inport %d spkron %d nintr %d\n", sc->out_port, sc->in_port, sc->spkr_state, sc->sc_interrupts); - printf("chans %x intr %x arg %x\n", - sc->sc_chans, sc->sc_intr, sc->sc_arg); + printf("precision %d channels %d intr %x arg %x\n", + sc->sc_precision, sc->sc_channels, sc->sc_intr, sc->sc_arg); printf("gain: "); for (i = 0; i < SB_NDEVS; i++) printf("%d ", sc->gain[i]); @@ -169,12 +170,15 @@ sbdsp_attach(sc) register int iobase = sc->sc_iobase; /* Set defaults */ - if (ISSBPROCLASS(sc)) - sc->sc_itc = sc->sc_otc = SBPRO_ADC_HS_MAX; + if (ISSB16CLASS(sc)) + sc->sc_irate = sc->sc_orate = 8000; + else if (ISSBPROCLASS(sc)) + sc->sc_itc = sc->sc_otc = SB_8K; else - sc->sc_itc = sc->sc_otc = SBCLA_ADC_HS_MAX; - sc->sc_chans = 1; - sc->encoding = AUDIO_ENCODING_LINEAR; + sc->sc_itc = sc->sc_otc = SB_8K; + 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); @@ -201,6 +205,18 @@ sbdsp_attach(sc) printf(": dsp v%d.%02d\n", SBVER_MAJOR(sc->sc_model), SBVER_MINOR(sc->sc_model)); + +#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 } /* @@ -238,7 +254,10 @@ sbdsp_set_in_sr(addr, sr) { register struct sbdsp_softc *sc = addr; - return (sbdsp_srtotc(sc, sr, SB_INPUT_RATE, &sc->sc_itc, &sc->sc_imode)); + if (ISSB16CLASS(sc)) + return (sbdsp_setrate(sc, sr, SB_INPUT_RATE, &sc->sc_irate)); + else + return (sbdsp_srtotc(sc, sr, SB_INPUT_RATE, &sc->sc_itc, &sc->sc_imode)); } u_long @@ -247,7 +266,10 @@ sbdsp_get_in_sr(addr) { register struct sbdsp_softc *sc = addr; - return (sbdsp_tctosr(sc, sc->sc_itc)); + if (ISSB16CLASS(sc)) + return (sc->sc_irate); + else + return (sbdsp_tctosr(sc, sc->sc_itc)); } int @@ -257,7 +279,10 @@ sbdsp_set_out_sr(addr, sr) { register struct sbdsp_softc *sc = addr; - return (sbdsp_srtotc(sc, sr, SB_OUTPUT_RATE, &sc->sc_otc, &sc->sc_omode)); + if (ISSB16CLASS(sc)) + return (sbdsp_setrate(sc, sr, SB_OUTPUT_RATE, &sc->sc_orate)); + else + return (sbdsp_srtotc(sc, sr, SB_OUTPUT_RATE, &sc->sc_otc, &sc->sc_omode)); } u_long @@ -266,7 +291,10 @@ sbdsp_get_out_sr(addr) { register struct sbdsp_softc *sc = addr; - return (sbdsp_tctosr(sc, sc->sc_otc)); + if (ISSB16CLASS(sc)) + return (sc->sc_orate); + else + return (sbdsp_tctosr(sc, sc->sc_otc)); } int @@ -292,13 +320,13 @@ sbdsp_query_encoding(addr, fp) } int -sbdsp_set_encoding(addr, enc) +sbdsp_set_encoding(addr, encoding) void *addr; - u_int enc; + u_int encoding; { register struct sbdsp_softc *sc = addr; - switch(enc){ + switch (encoding) { case AUDIO_ENCODING_ULAW: sc->encoding = AUDIO_ENCODING_ULAW; break; @@ -308,6 +336,7 @@ sbdsp_set_encoding(addr, enc) default: return (EINVAL); } + return (0); } @@ -321,13 +350,22 @@ sbdsp_get_encoding(addr) } int -sbdsp_set_precision(addr, prec) +sbdsp_set_precision(addr, precision) void *addr; - u_int prec; + u_int precision; { + register struct sbdsp_softc *sc = addr; + + if (ISSB16CLASS(sc)) { + if (precision != 16 && precision != 8) + return (EINVAL); + sc->sc_precision = precision; + } else { + if (precision != 8) + return (EINVAL); + sc->sc_precision = precision; + } - if (prec != 8) - return (EINVAL); return (0); } @@ -335,36 +373,32 @@ int sbdsp_get_precision(addr) void *addr; { - return (8); + register struct sbdsp_softc *sc = addr; + + return (sc->sc_precision); } int -sbdsp_set_channels(addr, chans) +sbdsp_set_channels(addr, channels) void *addr; - int chans; + int channels; { register struct sbdsp_softc *sc = addr; if (ISSBPROCLASS(sc)) { - if (chans != 1 && chans != 2) + if (channels != 1 && channels != 2) return (EINVAL); - sc->sc_chans = chans; - -#if 0 - if (rval = sbdsp_set_in_sr_real(addr, sc->sc_irate)) - return rval; -#endif - - sbdsp_mix_write(sc, SBP_STEREO, - (sbdsp_mix_read(sc, SBP_STEREO) & ~SBP_PLAYMODE_MASK) | - (chans == 2 ? SBP_PLAYMODE_STEREO : SBP_PLAYMODE_MONO)); - /* recording channels needs to be done right when we start - DMA recording. Just record number of channels for now - and set stereo when ready. */ + sc->sc_channels = channels; + sc->sc_dmadir = SB_DMA_NONE; + /* + * XXXX + * With 2 channels, SBPro can't do more than 22kHz. + * No framework to check this. + */ } else { - if (chans != 1) + if (channels != 1) return (EINVAL); - sc->sc_chans = chans; + sc->sc_channels = channels; } return (0); @@ -376,18 +410,7 @@ sbdsp_get_channels(addr) { register struct sbdsp_softc *sc = addr; -#if 0 - /* recording stereo may frob the mixer output */ - if (ISSBPROCLASS(sc)) { - if ((sbdsp_mix_read(sc, SBP_STEREO) & SBP_PLAYMODE_MASK) == SBP_PLAYMODE_STEREO) - sc->sc_chans = 2; - else - sc->sc_chans = 1; - } else - sc->sc_chans = 1; -#endif - - return (sc->sc_chans); + return (sc->sc_channels); } int @@ -555,13 +578,19 @@ sbdsp_round_blocksize(addr, blk) sc->sc_last_hs_size = 0; /* Higher speeds need bigger blocks to avoid popping and silence gaps. */ - if ((sc->sc_otc > SB_8K || sc->sc_itc > SB_8K) && - (blk > NBPG/2 || blk < NBPG/4)) - blk = NBPG/2; + 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. */ if (blk > NBPG) blk = NBPG; - if (sc->sc_chans == 2) + if (sc->sc_channels == 2) return (blk & ~1); /* must be even to preserve stereo separation */ else return (blk); /* Anything goes :-) */ @@ -671,6 +700,24 @@ sbdsp_reset(sc) return 0; } +int +sbdsp16_wait(iobase) + int iobase; +{ + register int i; + + for (i = SBDSP_NPOLL; --i >= 0; ) { + register u_char x; + x = inb(iobase + SBP_DSP_WSTAT); + delay(10); + if ((x & SB_DSP_BUSY) == 0) + continue; + return 0; + } + ++sberr.wdsp; + return -1; +} + /* * Write a byte to the dsp. * XXX We are at the mercy of the card as we use a @@ -814,6 +861,24 @@ sbdsp_contdma(addr) return(0); } +int +sbdsp_setrate(sc, sr, isdac, ratep) + register struct sbdsp_softc *sc; + int sr; + int isdac; + int *ratep; +{ + + /* + * XXXX + * More checks here? + */ + if (sr < 5000 || sr > 44100) + return (EINVAL); + *ratep = sr; + return (0); +} + /* * Convert a linear sampling rate into the DAC time constant. * Set *mode to indicate the high/low-speed DMA operation. @@ -902,7 +967,7 @@ sbdsp_tctosr(sc, tc) } int -sbdsp_set_tc(sc, tc) +sbdsp_set_timeconst(sc, tc) register struct sbdsp_softc *sc; int tc; { @@ -912,10 +977,10 @@ sbdsp_set_tc(sc, tc) * A SBPro in stereo mode uses time constants at double the * actual rate. */ - if (ISSBPRO(sc) && sc->sc_chans == 2) + if (ISSBPRO(sc) && sc->sc_channels == 2) tc = 256 - ((256 - tc) / 2); - DPRINTF(("sbdsp_set_tc: sc=%p tc=%d\n", 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 || @@ -940,15 +1005,15 @@ sbdsp_dma_input(addr, p, cc, intr, arg) if (sbdspdebug > 1) Dprintf("sbdsp_dma_input: cc=%d 0x%x (0x%x)\n", cc, intr, arg); #endif - if (sc->sc_chans == 2 && (cc & 1)) { + if (sc->sc_channels == 2 && (cc & 1)) { DPRINTF(("sbdsp_dma_input: stereo input, odd bytecnt\n")); return EIO; } iobase = sc->sc_iobase; if (sc->sc_dmadir != SB_DMA_IN) { - if (ISSBPROCLASS(sc)) { - if (sc->sc_chans == 2) { + if (ISSBPRO(sc)) { + if (sc->sc_channels == 2) { if (sbdsp_wdsp(iobase, SB_DSP_RECORD_STEREO) < 0) goto badmode; sbdsp_mix_write(sc, SBP_INFILTER, @@ -963,26 +1028,45 @@ sbdsp_dma_input(addr, p, cc, intr, arg) } } - sbdsp_set_tc(sc, sc->sc_itc); + 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) + goto giveup; + } else + sbdsp_set_timeconst(sc, sc->sc_itc); sc->sc_dmadir = SB_DMA_IN; } - isa_dmastart(B_READ, p, cc, sc->sc_drq); + isa_dmastart(DMAMODE_READ, p, cc, sc->sc_drq); sc->sc_intr = intr; sc->sc_arg = arg; - sc->dmaflags = B_READ; + sc->dmaflags = DMAMODE_READ; sc->dmaaddr = p; - sc->dmacnt = --cc; /* DMA controller is strange...? */ + sc->dmacnt = cc; /* DMA controller is strange...? */ - if (sc->sc_imode == SB_ADAC_LS) { + 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) | + (sc->sc_channels == 2 ? 0x20 : 0x00)) < 0 || + sbdsp16_wait(iobase) || + sbdsp_wdsp(iobase, cc) < 0 || + sbdsp_wdsp(iobase, 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 (cc != sc->sc_last_hs_size) { if (sbdsp_wdsp(iobase, SB_DSP_BLOCKSIZE) < 0 || sbdsp_wdsp(iobase, cc) < 0 || @@ -1005,7 +1089,7 @@ giveup: badmode: DPRINTF(("sbdsp_dma_input: can't set %s mode\n", - sc->sc_chans == 2 ? "stereo" : "mono")); + sc->sc_channels == 2 ? "stereo" : "mono")); return EIO; } @@ -1024,41 +1108,60 @@ sbdsp_dma_output(addr, p, cc, intr, arg) if (sbdspdebug > 1) Dprintf("sbdsp_dma_output: cc=%d 0x%x (0x%x)\n", cc, intr, arg); #endif - if (sc->sc_chans == 2 && (cc & 1)) { + if (sc->sc_channels == 2 && (cc & 1)) { DPRINTF(("stereo playback odd bytes (%d)\n", cc)); return EIO; } iobase = sc->sc_iobase; if (sc->sc_dmadir != SB_DMA_OUT) { - if (ISSBPROCLASS(sc)) { + if (ISSBPRO(sc)) { /* make sure we re-set stereo mixer bit when we start output. */ sbdsp_mix_write(sc, SBP_STEREO, (sbdsp_mix_read(sc, SBP_STEREO) & ~SBP_PLAYMODE_MASK) | - (sc->sc_chans == 2 ? SBP_PLAYMODE_STEREO : SBP_PLAYMODE_MONO)); + (sc->sc_channels == 2 ? SBP_PLAYMODE_STEREO : SBP_PLAYMODE_MONO)); } - sbdsp_set_tc(sc, sc->sc_otc); + 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) + goto giveup; + } else + sbdsp_set_timeconst(sc, sc->sc_otc); sc->sc_dmadir = SB_DMA_OUT; } - isa_dmastart(B_WRITE, p, cc, sc->sc_drq); + isa_dmastart(DMAMODE_WRITE, p, cc, sc->sc_drq); sc->sc_intr = intr; sc->sc_arg = arg; - sc->dmaflags = B_WRITE; + sc->dmaflags = DMAMODE_WRITE; 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_omode == SB_ADAC_LS) { + 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) | + (sc->sc_channels == 2 ? 0x20 : 0x00)) < 0 || + sbdsp16_wait(iobase) || + sbdsp_wdsp(iobase, cc) < 0 || + sbdsp_wdsp(iobase, 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 (cc != sc->sc_last_hs_size) { if (sbdsp_wdsp(iobase, SB_DSP_BLOCKSIZE) < 0 || sbdsp_wdsp(iobase, cc) < 0 || @@ -1099,13 +1202,15 @@ sbdsp_intr(arg) Dprintf("sbdsp_intr: intr=0x%x\n", sc->sc_intr); #endif if (!isa_dmafinished(sc->sc_drq)) { -#if 0 printf("sbdsp_intr: not finished\n"); -#endif return 0; } 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 @@ -1115,15 +1220,6 @@ sbdsp_intr(arg) } else #endif if (sc->sc_intr != 0) { - /* - * The SBPro used to develop and test this driver often - * generated dma underruns--it interrupted to signal - * completion of the DMA input recording block, but the - * ISA DMA controller didn't think the channel was - * finished. Maybe this is just a bus speed issue, I dunno, - * but it seems strange and leads to channel-flipping with - * stereo recording. Sigh. - */ isa_dmadone(sc->dmaflags, sc->dmaaddr, sc->dmacnt, sc->sc_drq); (*sc->sc_intr)(sc->sc_arg); } @@ -1172,14 +1268,14 @@ sbdsp_midi_output(sc, v) #endif u_int -sbdsp_get_silence(enc) - int enc; +sbdsp_get_silence(encoding) + int encoding; { #define ULAW_SILENCE 0x7f #define LINEAR_SILENCE 0 u_int auzero; - switch (enc) { + switch (encoding) { case AUDIO_ENCODING_ULAW: auzero = ULAW_SILENCE; break; diff --git a/sys/dev/isa/sbdspvar.h b/sys/dev/isa/sbdspvar.h index 67af95f3bc73..bf6eeefd129b 100644 --- a/sys/dev/isa/sbdspvar.h +++ b/sys/dev/isa/sbdspvar.h @@ -1,4 +1,4 @@ -/* $NetBSD: sbdspvar.h,v 1.10 1996/02/18 16:36:52 jtk Exp $ */ +/* $NetBSD: sbdspvar.h,v 1.11 1996/03/01 04:08:20 mycroft Exp $ */ /* * Copyright (c) 1991-1993 Regents of the University of California. @@ -79,7 +79,8 @@ struct sbdsp_softc { int sc_iobase; /* I/O port base address */ int sc_irq; /* interrupt */ - int sc_drq; /* DMA */ + int sc_drq; /* DMA (8-bit) */ + int sc_drq16; /* DMA (16-bit) */ u_short sc_open; /* reference count of open calls */ @@ -94,8 +95,8 @@ struct sbdsp_softc { u_int spkr_state; /* non-null is on */ - int sc_itc; /* Sample rate for input */ - int sc_otc; /* ...and output */ + int sc_irate, sc_itc; /* Sample rate for input */ + int sc_orate, sc_otc; /* ...and output */ int sc_imode; int sc_omode; @@ -111,7 +112,8 @@ struct sbdsp_softc { caddr_t dmaaddr; vm_size_t dmacnt; int sc_last_hs_size; /* last HS dma size */ - int sc_chans; /* # of channels */ + 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 @@ -122,14 +124,14 @@ struct sbdsp_softc { #define SBVER_MINOR(v) ((v)&0xff) }; -#define ISSBPRO(sc) \ - (SBVER_MAJOR((sc)->sc_model) == 3) - #define ISSBPROCLASS(sc) \ (SBVER_MAJOR((sc)->sc_model) > 2) +#define ISSBPRO(sc) \ + (SBVER_MAJOR((sc)->sc_model) == 3) + #define ISSB16CLASS(sc) \ - (SBVER_MAJOR((sc)->sc_model) > 3) + (SBVER_MAJOR((sc)->sc_model) > 3) #ifdef _KERNEL diff --git a/sys/dev/isa/sbreg.h b/sys/dev/isa/sbreg.h index 91b058b2e001..433a84da9127 100644 --- a/sys/dev/isa/sbreg.h +++ b/sys/dev/isa/sbreg.h @@ -1,4 +1,4 @@ -/* $NetBSD: sbreg.h,v 1.14 1996/02/20 11:15:17 mycroft Exp $ */ +/* $NetBSD: sbreg.h,v 1.15 1996/03/01 04:08:13 mycroft Exp $ */ /* * Copyright (c) 1991-1993 Regents of the University of California. @@ -150,6 +150,8 @@ #define SB_MIDI_UART_INTR 0x35 /* enter UART mode w/ read intrs */ #define SB_MIDI_WRITE 0x38 /* write a MIDI byte (non-UART mode) */ #define SB_DSP_TIMECONST 0x40 /* set ADAC time constant */ +#define SB_DSP16_OUTPUTRATE 0x41 /* set ADAC output rate */ +#define SB_DSP16_INPUTRATE 0x42 /* set ADAC input rate */ #define SB_DSP_BLOCKSIZE 0x48 /* set blk size for high speed xfer */ #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 */ @@ -158,6 +160,10 @@ #define SB_DSP_HS_INPUT 0x99 /* 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 */ +#define SB_DSP16_RDMA_16 0xBE /* begin 16-bit linear input */ +#define SB_DSP16_WDMA_8 0xC6 /* begin 8-bit linear output */ +#define SB_DSP16_RDMA_8 0xCE /* begin 8-bit linear input */ #define SB_DSP_HALT 0xd0 /* temporarilty suspend DMA */ #define SB_DSP_SPKR_ON 0xd1 /* turn speaker on */ #define SB_DSP_SPKR_OFF 0xd3 /* turn speaker off */ diff --git a/sys/dev/isa/wd.c b/sys/dev/isa/wd.c index 9e296c91ee93..da2ed01e4d96 100644 --- a/sys/dev/isa/wd.c +++ b/sys/dev/isa/wd.c @@ -1,4 +1,4 @@ -/* $NetBSD: wd.c,v 1.145 1996/01/08 21:21:56 mycroft Exp $ */ +/* $NetBSD: wd.c,v 1.146 1996/03/01 04:08:51 mycroft Exp $ */ /* * Copyright (c) 1994, 1995 Charles M. Hannum. All rights reserved. @@ -53,6 +53,7 @@ #include #include +#include #include #define WAITTIME (4 * hz) /* time to wait for a completion */ @@ -661,7 +662,8 @@ loop: WDCC_READDMA : WDCC_WRITEDMA; /* Start the DMA channel and bounce the buffer if necessary. */ - isa_dmastart(bp->b_flags & B_READ, + isa_dmastart( + bp->b_flags & B_READ ? DMAMODE_READ : DMAMODE_WRITE, bp->b_data + wd->sc_skip, wd->sc_nbytes, wdc->sc_drq); break; @@ -765,8 +767,8 @@ wdcintr(arg) /* Turn off the DMA channel and unbounce the buffer. */ if (wd->sc_mode == WDM_DMA) - isa_dmadone(bp->b_flags & B_READ, bp->b_data + wd->sc_skip, - wd->sc_nbytes, wdc->sc_drq); + isa_dmadone(bp->b_flags & B_READ ? DMAMODE_READ : DMAMODE_WRITE, + bp->b_data + wd->sc_skip, wd->sc_nbytes, wdc->sc_drq); /* Have we an error? */ if (wdc->sc_status & WDCS_ERR) { diff --git a/sys/dev/isa/wt.c b/sys/dev/isa/wt.c index b714c74d4f2f..de1800be8abf 100644 --- a/sys/dev/isa/wt.c +++ b/sys/dev/isa/wt.c @@ -1,4 +1,4 @@ -/* $NetBSD: wt.c,v 1.28 1996/01/12 00:54:23 thorpej Exp $ */ +/* $NetBSD: wt.c,v 1.29 1996/03/01 04:08:40 mycroft Exp $ */ /* * Streamer tape driver. @@ -138,7 +138,7 @@ struct wt_softc { void *dmavaddr; /* virtual address of dma i/o buffer */ size_t dmatotal; /* size of i/o buffer */ - int dmaflags; /* i/o direction, B_READ or B_WRITE */ + int dmaflags; /* i/o direction */ size_t dmacount; /* resulting length of dma i/o */ u_short error; /* code for error encountered */ @@ -668,7 +668,7 @@ wtintr(arg) /* * Clean up dma. */ - if ((sc->dmaflags & B_READ) && + if ((sc->dmaflags & DMAMODE_READ) && (sc->dmatotal - sc->dmacount) < sc->bsize) { /* If reading short block, copy the internal buffer * to the user memory. */ @@ -682,7 +682,7 @@ wtintr(arg) */ if ((x & sc->NOEXCEP) == 0) { WTDBPRINT(("i/o exception\n")); - wtsense(sc, 1, (sc->dmaflags & B_READ) ? TP_WRP : 0); + wtsense(sc, 1, (sc->dmaflags & DMAMODE_READ) ? TP_WRP : 0); if (sc->error & (TP_EOM | TP_FIL)) sc->flags |= TPVOL; /* end of file */ else @@ -857,7 +857,7 @@ wtdma(sc) outb(sc->SDMAPORT, 0); } - if ((sc->dmaflags & B_READ) && + if ((sc->dmaflags & DMAMODE_READ) && (sc->dmatotal - sc->dmacount) < sc->bsize) { /* Reading short block; do it through the internal buffer. */ isa_dmastart(sc->dmaflags, sc->buf, sc->bsize, sc->chan); @@ -885,7 +885,7 @@ wtstart(sc, flag, vaddr, len) sc->dmavaddr = vaddr; sc->dmatotal = len; sc->dmacount = 0; - sc->dmaflags = flag; + sc->dmaflags = flag & B_READ ? DMAMODE_READ : DMAMODE_WRITE; wtdma(sc); return 1; }