From 1a4973fcbda0d2ef24578c623aaf0c180f0a1020 Mon Sep 17 00:00:00 2001 From: mickey Date: Wed, 24 Apr 1996 16:51:14 +0000 Subject: [PATCH] Add OPTi 82C929 chipset support for sound(wss,sb)/cd(mcd,scd,pcd,atapi) card. This is software programable card. Missing: SB support (no srcs available, and dos's exe is too big ;) Not tested: pcd(panasonic cd)(no driver); mcd,atapi(have no hw). --- sys/dev/isa/mcd.c | 6 +- sys/dev/isa/opti.c | 298 +++++++++++++++++++++++++++++++++++++++++++++ sys/dev/isa/opti.h | 66 ++++++++++ sys/dev/isa/wss.c | 10 +- 4 files changed, 377 insertions(+), 3 deletions(-) create mode 100644 sys/dev/isa/opti.c create mode 100644 sys/dev/isa/opti.h diff --git a/sys/dev/isa/mcd.c b/sys/dev/isa/mcd.c index cf5eeb3a812..0381f74e1fd 100644 --- a/sys/dev/isa/mcd.c +++ b/sys/dev/isa/mcd.c @@ -1,4 +1,4 @@ -/* $OpenBSD: mcd.c,v 1.9 1996/04/21 22:24:21 deraadt Exp $ */ +/* $OpenBSD: mcd.c,v 1.10 1996/04/24 16:51:16 mickey Exp $ */ /* $NetBSD: mcd.c,v 1.47 1996/04/11 22:29:43 cgd Exp $ */ /* @@ -78,6 +78,7 @@ #include #include +#include #ifndef MCDDEBUG #define MCD_TRACE(fmt,a,b,c,d) @@ -753,6 +754,9 @@ mcdprobe(parent, match, aux) sc->iobase = iobase; + if( !opti_cd_setup( OPTI_MITSUMI, iobase, ia->ia_irq, ia->ia_drq ) ) + /* printf("mcdprobe: could not setup OPTi chipset.\n") */; + /* Send a reset. */ outb(iobase + MCD_RESET, 0); delay(1000000); diff --git a/sys/dev/isa/opti.c b/sys/dev/isa/opti.c new file mode 100644 index 00000000000..1500f98e4d2 --- /dev/null +++ b/sys/dev/isa/opti.c @@ -0,0 +1,298 @@ +/* $OpenBSD: opti.c,v 1.1 1996/04/24 16:51:14 mickey Exp $ */ + +/* + * Copyright (c) 1996 Michael Shalayeff + * + * 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 Michael Shalayeff. + * 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. + * + */ + +/* + * Code to setup 82C929 chipset + */ + +#define OPTI_DEBUG 9 + +#include +#include +#include +#include +#include + +#include + +#include +#include + +#include + +#ifdef OPTI_DEBUG + int opti_debuglevel = OPTI_DEBUG; +# define XDEBUG(level, data) ((opti_debuglevel >= level)? printf data:0) +#else +# define XDEBUG(level, data) /* ((opti_debuglevel >= level)? printf data:0) */ +#endif + +#define OPTI_cd_valid_ift(i) ((i)==OPTI_SONY||(i)==OPTI_PANASONIC||\ + (i)==OPTI_MITSUMI||(i)==OPTI_IDE) +static __inline int +OPTI_cd_addr(a) + int a; +{ + switch(a) { + case 0x320: return 0xc0; + case 0x330: return 0x40; + case 0x340: return 0x00; + case 0x360: return 0x80; + default: return -1; + } +} +static __inline int +OPTI_cd_irq(i) + int i; +{ + switch(i) { + case 5: return 0x04; + case 7: return 0x08; + case 3: return 0x0c; + case 9: return 0x10; + case 10:return 0x14; + case 11:return 0x18; + case -1:return 0x00; + default:return -1; + } +} +static __inline int +OPTI_cd_drq(d) + int d; +{ + switch(d) { + case 3: + case 5: return 0; + case 6: return 1; + case 7: return 2; + default:return 3; + } +} + +#define OPTI_snd_valid_ift(i) ((i)==OPTI_WSS||(i)==OPTI_SB) + +static __inline int +OPTI_snd_addr(a) + int a; +{ + switch(a) { + case 0x220: return 0x0; + case 0x240: return 0x3; + case 0x530: return 0x8; + case 0xE80: return 0x9; + case 0xF40: return 0xa; + case 0x604: return 0xb; + default: return -1; + } +} +static __inline int +OPTI_snd_irq(i) + int i; +{ + switch(i) { + case 5: return 0x04; + case 7: return 0x08; + case 3: return 0x0c; + case 9: return 0x10; + case 10:return 0x14; + case 11:return 0x18; + case -1:return 0x00; + default:return -1; + } +} +static __inline int +OPTI_snd_drq(d) + int d; +{ + switch(d) { + case 3: + case 5: return 0; + case 6: return 1; + case 7: return 2; + default:return 3; + } +} + +static int +opti_present( void ) +{ + register u_char a, b; + int s = splhigh(); + + outb( OPTI_CTRL, 0xe3 ); + a = inb( OPTI_CTRL ); + + outb( OPTI_CTRL, 0xe3 ); + outb( OPTI_CTRL, 0x00 ); + + outb( OPTI_CTRL, 0xe3 ); + b = inb( OPTI_CTRL ); + + outb( OPTI_CTRL, 0xe3 ); + outb( OPTI_CTRL, a ); + + splx(s); + + return b == 2; +} + +int +opti_cd_setup( ift, addr, irq, drq ) + int ift, addr, irq, drq; +{ + int ret = 0; + + XDEBUG( 2, ("opti: do CD setup t=%u, a=0x%x, i=%d, d=%d\n", + ift, addr, irq, drq)); + + if( !opti_present() ) + XDEBUG( 2, ("opti: not present.\n")); + else if( !OPTI_cd_valid_ift(ift) ) + XDEBUG( 2, ("opti: invalid CD-ROM interface type.\n")); + else if( OPTI_cd_addr(addr) == -1) + XDEBUG( 2, ("opti: illegal CD-ROM interface address.\n")); + else if( OPTI_cd_irq(irq) == -1) + XDEBUG( 2, ("opti: wrong CD-ROM irq number.\n")); + else if( OPTI_cd_drq(drq) == -1) + XDEBUG( 2, ("opti: bad CD_ROM drq number.\n")); + else + { + /* so the setup */ + int s = splhigh(); + register u_char a, b; + + /* set interface type */ + outb( OPTI_CTRL, 0xe3 ); + a = inb( OPTI_IFTP ); + + outb( OPTI_CTRL, 0xe3 ); + b = (inb( OPTI_DATA ) & 0x20) | 3 ; + + outb( OPTI_CTRL, 0xe3 ); + outb( OPTI_DATA, b ); + + outb( OPTI_CTRL, 0xe3 ); + outb( OPTI_IFTP, (a & 0xf1) | 2*ift ); + + outb( OPTI_CTRL, 0xe3 ); + outb( OPTI_ENBL, 0x80 ); + + /* we don't need any additional setup for IDE CD-ROM */ + if( ift != OPTI_IDE ) + { + /* set address */ + outb( OPTI_CTRL, 0xe3 ); + a = inb( OPTI_DATA ); + + outb( OPTI_CTRL, 0xe3 ); + outb( OPTI_DATA, (a & 0x3f) | + (0x40 * OPTI_cd_addr(addr)) ); + + /* set irq */ + if( irq != IRQUNK ) + { + outb( OPTI_CTRL, 0xe3 ); + a = inb( OPTI_DATA ); + + outb( OPTI_CTRL, 0xe3 ); + outb( OPTI_DATA, (inb( OPTI_DATA ) & 0xe3) | + OPTI_cd_irq(irq) ); + } + + /* set drq */ + if( drq != DRQUNK ) + { + outb( OPTI_CTRL, 0xe3 ); + a = inb( OPTI_DATA ); + + outb( OPTI_CTRL, 0xe3 ); + outb( OPTI_DATA, (inb( OPTI_DATA ) & 0xfc) | + OPTI_cd_drq(drq) ); + } + } + splx(s); + DELAY(1000); + ret = 1; + } + + return ret; +} + +int +opti_snd_setup( ift, addr, irq, drq ) + int ift, addr, irq, drq; +{ + XDEBUG( 2, ("opti: do SND setup t=%u,a=%x,i=%d,d=%d\n", + ift, addr, irq, drq)); + + if( !opti_present() ) + XDEBUG( 2, ("opti: not present.\n")); + else if( !OPTI_snd_valid_ift(ift) ) + XDEBUG( 2, ("opti: invalid SND interface type.\n")); + else if( OPTI_snd_addr(addr) == -1) + XDEBUG( 2, ("opti: illegal SND interface address.\n")); + else if( OPTI_snd_irq(irq) == -1) + XDEBUG( 2, ("opti: wrong SND irq number.\n")); + else if( OPTI_snd_drq(drq) == -1) + XDEBUG( 2, ("opti: bad SND drq number.\n")); + else + { + /* so the setup */ + int s = splhigh(); + register u_char a, b; + + if (ift == OPTI_WSS) { + outb( OPTI_CTRL, 0xe3 ); + a = inb( OPTI_CTRL ); + + outb( OPTI_CTRL, 0xe3 ); + outb( OPTI_ENBL, 0x1a ); + + outb( OPTI_CTRL, 0xe3 ); + outb( OPTI_IFTP, OPTI_snd_addr(addr)*16 + 1 ); + + outb( OPTI_CTRL, 0xe3 ); + outb( OPTI_ENBL, 0x1a ); + + outb( OPTI_CTRL, 0xe3 ); + outb( OPTI_CTRL, a ); + } + + splx(s); + DELAY(1000); + return 1; + } + + return 0; +} diff --git a/sys/dev/isa/opti.h b/sys/dev/isa/opti.h new file mode 100644 index 00000000000..c8d1dc45bf3 --- /dev/null +++ b/sys/dev/isa/opti.h @@ -0,0 +1,66 @@ +/* $OpenBSD: opti.h,v 1.1 1996/04/24 16:51:14 mickey Exp $ */ + +/* + * Copyright (c) 1996 Michael Shalayeff + * + * 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 Michael Shalayeff. + * 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. + * + */ + +#ifndef __OPTI_HEADER__ +#define __OPTI_HEADER__ + + /* i/o ports */ +#define OPTI_4 0xF84 +#define OPTI_5 0xF85 +#define OPTI_DATA 0xF8E +#define OPTI_IFTP 0xF8D /* iface control register */ +#define OPTI_CTRL 0xF8F +#define OPTI_ENBL 0xF91 + + /* CD-ROM iface setup */ + + /* CD-ROM interface types */ +#define OPTI_DISABLE 0 +#define OPTI_SONY 1 +#define OPTI_MITSUMI 2 +#define OPTI_PANASONIC 3 +#define OPTI_IDE 4 + + /* Sound system setup */ + + /* Sound iface types */ +#define OPTI_WSS (0) /* Windows Sound System */ +#define OPTI_SB (1) /* Sound Blaster Pro(tm) compatible */ + +#ifdef _KERNEL +int opti_cd_setup __P(( int, int, int, int )); +int opti_snd_setup __P(( int, int, int, int )); +#endif + +#endif /* __OPTI_HEADER__ */ diff --git a/sys/dev/isa/wss.c b/sys/dev/isa/wss.c index ba0b2fb7df2..7e9b14296bf 100644 --- a/sys/dev/isa/wss.c +++ b/sys/dev/isa/wss.c @@ -1,4 +1,4 @@ -/* $OpenBSD: wss.c,v 1.8 1996/04/21 22:24:49 deraadt Exp $ */ +/* $OpenBSD: wss.c,v 1.9 1996/04/24 16:51:15 mickey Exp $ */ /* $NetBSD: wss.c,v 1.11 1996/04/11 22:30:46 cgd Exp $ */ /* @@ -57,6 +57,7 @@ #include #include #include +#include /* * Mixer devices @@ -194,11 +195,16 @@ wssprobe(parent, match, aux) return 0; } + if( !opti_snd_setup( OPTI_WSS, iobase, ia->ia_irq, ia->ia_drq ) ) + printf("ad_detect_A: could not setup OPTi chipset.\n"); + sc->sc_ad1848.sc_iobase = iobase; /* Is there an ad1848 chip at the WSS iobase ? */ - if (ad1848_probe(&sc->sc_ad1848) == 0) + if (ad1848_probe(&sc->sc_ad1848) == 0) { + printf("ad_detect_A: no ad1848 found.\n"); return 0; + } ia->ia_iosize = WSS_NPORT; -- 2.20.1