Add OPTi 82C929 chipset support for sound(wss,sb)/cd(mcd,scd,pcd,atapi)
authormickey <mickey@openbsd.org>
Wed, 24 Apr 1996 16:51:14 +0000 (16:51 +0000)
committermickey <mickey@openbsd.org>
Wed, 24 Apr 1996 16:51:14 +0000 (16:51 +0000)
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
sys/dev/isa/opti.c [new file with mode: 0644]
sys/dev/isa/opti.h [new file with mode: 0644]
sys/dev/isa/wss.c

index cf5eeb3..0381f74 100644 (file)
@@ -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 <dev/isa/isavar.h>
 #include <dev/isa/mcdreg.h>
+#include <dev/isa/opti.h>
 
 #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 (file)
index 0000000..1500f98
--- /dev/null
@@ -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 <sys/param.h>
+#include <sys/types.h>
+#include <sys/kernel.h>
+#include <sys/conf.h>
+#include <sys/device.h>
+
+#include <machine/pio.h>
+
+#include <i386/isa/icu.h>
+#include <dev/isa/isavar.h>
+
+#include <dev/isa/opti.h>
+
+#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 (file)
index 0000000..c8d1dc4
--- /dev/null
@@ -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__ */
index ba0b2fb..7e9b142 100644 (file)
@@ -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 <dev/ic/ad1848reg.h>
 #include <dev/isa/ad1848var.h>
 #include <dev/isa/wssreg.h>
+#include <dev/isa/opti.h>
 
 /*
  * 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;