From 95abb133dc7e942232f49498108c6e007a2047b5 Mon Sep 17 00:00:00 2001 From: mycroft Date: Thu, 20 Mar 1997 11:03:10 +0000 Subject: [PATCH] Add 16-bit DRQ support on PnP, and enable 16-bit output. --- sys/dev/isa/sb.c | 68 ++++++++++++++++++++++++++++---------- sys/dev/isa/sb_isa.c | 5 +-- sys/dev/isa/sbdsp.c | 68 ++++++++++++++++---------------------- sys/dev/isa/sbdspvar.h | 5 +-- sys/dev/isa/sbreg.h | 14 +++++--- sys/dev/isapnp/sb_isapnp.c | 4 +-- 6 files changed, 96 insertions(+), 68 deletions(-) diff --git a/sys/dev/isa/sb.c b/sys/dev/isa/sb.c index b012cf382f11..997d1b2ca4f7 100644 --- a/sys/dev/isa/sb.c +++ b/sys/dev/isa/sb.c @@ -1,4 +1,4 @@ -/* $NetBSD: sb.c,v 1.42 1997/03/20 06:48:57 mycroft Exp $ */ +/* $NetBSD: sb.c,v 1.43 1997/03/20 11:03:10 mycroft Exp $ */ /* * Copyright (c) 1991-1993 Regents of the University of California. @@ -129,8 +129,8 @@ int sbmatch(sc) struct sbdsp_softc *sc; { - 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] = { @@ -141,27 +141,35 @@ sbmatch(sc) 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(sc->sc_drq)) { + if (!SBP_DRQ_VALID(sc->sc_drq8)) { printf("%s: configured dma chan %d invalid\n", - sc->sc_dev.dv_xname, sc->sc_drq); + sc->sc_dev.dv_xname, sc->sc_drq8); return 0; } - if (ISSB16CLASS(sc)) - sbdsp_mix_write(sc, SBP_SET_DRQ, drq_conf[sc->sc_drq]); - } - else { - if (!SB_DRQ_VALID(sc->sc_drq)) { + } else { + if (!SB_DRQ_VALID(sc->sc_drq8)) { printf("%s: configured dma chan %d invalid\n", - sc->sc_dev.dv_xname, sc->sc_drq); + 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. @@ -191,16 +199,42 @@ sbmatch(sc) sc->sc_dev.dv_xname, sc->sc_irq); return 0; } - if (ISSB16CLASS(sc)) - sbdsp_mix_write(sc, SBP_SET_IRQ, irq_conf[sc->sc_irq]); - } - else { + } 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 (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; } @@ -240,7 +274,7 @@ sbforceintr(aux) * it is needed (and you pay the latency). Also, you might * never need the buffer anyway.) */ - at_dma(DMAMODE_READ, &dmabuf, 1, sc->sc_drq); + 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); diff --git a/sys/dev/isa/sb_isa.c b/sys/dev/isa/sb_isa.c index bfaf27d20313..f17e58632b4c 100644 --- a/sys/dev/isa/sb_isa.c +++ b/sys/dev/isa/sb_isa.c @@ -1,4 +1,4 @@ -/* $NetBSD: sb_isa.c,v 1.2 1997/02/12 23:37:38 thorpej 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. @@ -99,7 +99,8 @@ sb_isa_match(parent, match, aux) */ sc->sc_iobase = ia->ia_iobase; sc->sc_irq = ia->ia_irq; - sc->sc_drq = ia->ia_drq; + sc->sc_drq8 = ia->ia_drq; + sc->sc_drq16 = -1; /* XXX */ sc->sc_ic = ia->ia_ic; if (!sbmatch(sc)) { diff --git a/sys/dev/isa/sbdsp.c b/sys/dev/isa/sbdsp.c index 7692c18af534..92647e6d3acf 100644 --- a/sys/dev/isa/sbdsp.c +++ b/sys/dev/isa/sbdsp.c @@ -1,4 +1,4 @@ -/* $NetBSD: sbdsp.c,v 1.34 1997/03/20 06:48:58 mycroft Exp $ */ +/* $NetBSD: sbdsp.c,v 1.35 1997/03/20 11:03:13 mycroft Exp $ */ /* * Copyright (c) 1991-1993 Regents of the University of California. @@ -123,7 +123,7 @@ u_int sbdsp_jazz16_probe __P((struct sbdsp_softc *)); 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)); @@ -138,8 +138,8 @@ 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->sc_drq, 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->sc_encoding); @@ -202,7 +202,7 @@ sbdsp_jazz16_probe(sc) if (bus_space_map(iot, JAZZ16_CONFIG_PORT, 1, 0, &ioh)) return rval; - if (jazz16_drq_conf[sc->sc_drq] == (u_char)-1 || + if (jazz16_drq_conf[sc->sc_drq8] == (u_char)-1 || jazz16_irq_conf[sc->sc_irq] == (u_char)-1) goto done; /* give up, we can't do it. */ @@ -220,10 +220,11 @@ sbdsp_jazz16_probe(sc) if (sbdsp_rdsp(sc) != JAZZ16_VER_JAZZ) goto done; + /* 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) || - /* set both 8 & 16-bit drq to same channel, it works fine. */ - sbdsp_wdsp(sc, (jazz16_drq_conf[sc->sc_drq] << 4) | - jazz16_drq_conf[sc->sc_drq]) || + 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")); else @@ -280,18 +281,6 @@ sbdsp_attach(sc) printf(": dsp v%d.%02d%s\n", SBVER_MAJOR(sc->sc_model), SBVER_MINOR(sc->sc_model), ISJAZZ16(sc) ? ": " : ""); - -#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 } /* @@ -334,7 +323,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)); } @@ -359,7 +348,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)); } @@ -483,6 +472,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) { @@ -511,6 +501,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; @@ -589,6 +580,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, @@ -961,7 +953,7 @@ sbdsp_contdma(addr) } int -sbdsp_setrate(sc, sr, isdac, ratep) +sbdsp16_setrate(sc, sr, isdac, ratep) register struct sbdsp_softc *sc; int sr; int isdac; @@ -972,7 +964,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); @@ -1156,6 +1148,7 @@ sbdsp_dma_input(addr, p, cc, intr, arg) sc->sc_dmadir = SB_DMA_IN; } + sc->sc_drq = sc->sc_precision == 16 ? sc->sc_drq16 : sc->sc_drq8; isa_dmastart(DMAMODE_READ, p, cc, sc->sc_drq); sc->sc_intr = intr; sc->sc_arg = arg; @@ -1163,13 +1156,12 @@ sbdsp_dma_input(addr, p, cc, intr, arg) 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(sc, sc->sc_precision == 16 ? SB_DSP16_RDMA_16 : - SB_DSP16_RDMA_8) < 0 || + SB_DSP16_RDMA_8) < 0 || sbdsp_wdsp(sc, (sc->sc_precision == 16 ? 0x10 : 0x00) | (sc->sc_channels == 2 ? 0x20 : 0x00)) < 0 || sbdsp16_wait(sc) || @@ -1265,6 +1257,7 @@ sbdsp_dma_output(addr, p, cc, intr, arg) sc->sc_dmadir = SB_DMA_OUT; } + sc->sc_drq = sc->sc_precision == 16 ? sc->sc_drq16 : sc->sc_drq8; isa_dmastart(DMAMODE_WRITE, p, cc, sc->sc_drq); sc->sc_intr = intr; sc->sc_arg = arg; @@ -1272,13 +1265,12 @@ sbdsp_dma_output(addr, p, cc, intr, arg) 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(sc, sc->sc_precision == 16 ? SB_DSP16_WDMA_16 : - SB_DSP16_WDMA_8) < 0 || + SB_DSP16_WDMA_8) < 0 || sbdsp_wdsp(sc, (sc->sc_precision == 16 ? 0x10 : 0x00) | (sc->sc_channels == 2 ? 0x20 : 0x00)) < 0 || sbdsp16_wait(sc) || @@ -1335,18 +1327,10 @@ sbdsp_intr(arg) Dprintf("sbdsp_intr: intr=0x%x\n", sc->sc_intr); #endif if (!isa_dmafinished(sc->sc_drq)) { -#ifdef AUDIO_DEBUG printf("sbdsp_intr: not finished\n"); -#endif return 0; } sc->sc_interrupts++; - /* clear interrupt */ -#ifdef notyet - x = sbdsp_mix_read(sc, 0x82); - x = bus_space_read_1(sc->sc_iot, sc->sc_ioh, 15); -#endif - x = bus_space_read_1(sc->sc_iot, sc->sc_ioh, SBP_DSP_RSTAT); delay(10); #if 0 if (sc->sc_mintr != 0) { @@ -1355,11 +1339,15 @@ sbdsp_intr(arg) } else #endif if (sc->sc_intr != 0) { + /* clear interrupt */ + x = bus_space_read_1(sc->sc_iot, sc->sc_ioh, + sc->sc_precision == 16 ? SBP_DSP_IRQACK16 : + SBP_DSP_IRQACK8); isa_dmadone(sc->dmaflags, sc->dmaaddr, sc->dmacnt, sc->sc_drq); (*sc->sc_intr)(sc->sc_arg); - } - else + } else { return 0; + } return 1; } diff --git a/sys/dev/isa/sbdspvar.h b/sys/dev/isa/sbdspvar.h index 2f60c7434456..9e35fa71668f 100644 --- a/sys/dev/isa/sbdspvar.h +++ b/sys/dev/isa/sbdspvar.h @@ -1,4 +1,4 @@ -/* $NetBSD: sbdspvar.h,v 1.16 1997/03/20 06:48:59 mycroft Exp $ */ +/* $NetBSD: sbdspvar.h,v 1.17 1997/03/20 11:03:14 mycroft Exp $ */ /* * Copyright (c) 1991-1993 Regents of the University of California. @@ -82,7 +82,8 @@ struct sbdsp_softc { int sc_iobase; /* I/O port base address */ int sc_irq; /* interrupt */ - int sc_drq; /* DMA (8-bit) */ + int sc_drq; /* active DMA channel */ + int sc_drq8; /* DMA (8-bit) */ int sc_drq16; /* DMA (16-bit) */ u_short sc_open; /* reference count of open calls */ diff --git a/sys/dev/isa/sbreg.h b/sys/dev/isa/sbreg.h index 54be46519bcd..9c2f08d7a583 100644 --- a/sys/dev/isa/sbreg.h +++ b/sys/dev/isa/sbreg.h @@ -1,4 +1,4 @@ -/* $NetBSD: sbreg.h,v 1.16 1996/03/16 04:00:14 jtk Exp $ */ +/* $NetBSD: sbreg.h,v 1.17 1997/03/20 11:03:16 mycroft Exp $ */ /* * Copyright (c) 1991-1993 Regents of the University of California. @@ -122,6 +122,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 */ @@ -160,10 +162,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_DSP16_WDMA_16 0xB2 /* begin 16-bit linear output */ +#define SB_DSP16_RDMA_16 0xBA /* begin 16-bit linear input */ +#define SB_DSP16_WDMA_8 0xC2 /* begin 8-bit linear output */ +#define SB_DSP16_RDMA_8 0xCA /* 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 */ @@ -229,6 +231,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/isapnp/sb_isapnp.c b/sys/dev/isapnp/sb_isapnp.c index c2034a99d8b7..001253bb612f 100644 --- a/sys/dev/isapnp/sb_isapnp.c +++ b/sys/dev/isapnp/sb_isapnp.c @@ -1,4 +1,4 @@ -/* $NetBSD: sb_isapnp.c,v 1.2 1997/03/13 01:45:11 christos Exp $ */ +/* $NetBSD: sb_isapnp.c,v 1.3 1997/03/20 11:03:18 mycroft Exp $ */ /* * Copyright (c) 1991-1993 Regents of the University of California. @@ -105,7 +105,7 @@ sb_isapnp_attach(parent, self, aux) sc->sc_ioh = ipa->ipa_io[0].h; sc->sc_irq = ipa->ipa_irq[0].num; - sc->sc_drq = ipa->ipa_drq[0].num; + sc->sc_drq8 = ipa->ipa_drq[0].num; sc->sc_drq16 = ipa->ipa_drq[1].num; printf("\n");