NetBSD Problem Report #9196

Received: (qmail 28101 invoked from network); 15 Jan 2000 12:56:00 -0000
Message-Id: <20000115215048W.mer@din.or.jp>
Date: Sat, 15 Jan 2000 21:50:48 +0900
From: "Yamano-uchi, Hidetoshi" (=?ISO-2022-JP?B?GyRAOzNGYhsoSg==?=
	=?ISO-2022-JP?B?IBskQDFRSVIbKEo=?=) <mer@din.or.jp>
To: gnats-bugs@netbsd.org
Subject: OPTi93x probe routines on wss.

>Number:         9196
>Category:       kern
>Synopsis:       OPTi93x audio
>Confidential:   no
>Severity:       non-critical
>Priority:       medium
>Responsible:    kern-bug-people
>State:          open
>Class:          sw-bug
>Submitter-Id:   net
>Arrival-Date:   Sat Jan 15 04:57:00 +0000 2000
>Closed-Date:    
>Last-Modified:  Mon Jun 05 20:26:56 +0000 2000
>Originator:     Yamano-uchi, Hidetoshi
>Release:        1.4.1
>Organization:
>Environment:
System: NetBSD printemps 1.4.1 NetBSD 1.4.1 (PRINTEMPS_OPTI) #43: Sat Jan 15 20:38:20 JST 2000 mer@printemps:/sys/arch/i386/compile/PRINTEMPS_OPTI i386
and kern/8443 patch is applied.

>Description:
I wrote probe routines on OPTi 933.  It works on Onkyo Wavio SE-70(OPTi 933?).
I tested only
	PCM playback(/dev/audio and ump in Linux emulation)
	CD playback.

DAC volume:	inputs.dac
CD  volume:	inputs.cd
master volume:	monitor.monitor

P.S. **** Cleaning up is NEEDED!!! ****
P.S.2 URI on the data sheet is
  ftp://ftp.opti.com/pub/chipsets/sound/82c931/db035_21.pdf
(or http://www.ectiva.org ????)

>How-To-Repeat:
>Fix:
diff -ur /sys/dev/ic/ad1848.c dev/ic/ad1848.c
--- /sys/dev/ic/ad1848.c	Fri Feb 19 02:27:39 1999
+++ dev/ic/ad1848.c	Sat Jan 15 20:26:54 2000
@@ -124,6 +124,10 @@
 #include <dev/isa/cs4231var.h>
 #endif

+#if 1
+#include <dev/ic/opti93xreg.h>
+#endif
+
 #ifdef AUDIO_DEBUG
 #define DPRINTF(x)	if (ad1848debug) printf x
 int	ad1848debug = 0;
@@ -134,6 +138,7 @@
 /*
  * Initial values for the indirect registers of CS4248/AD1848.
  */
+#if 0
 static int ad1848_init_values[] = {
     GAIN_12|INPUT_MIC_GAIN_ENABLE,	/* Left Input Control */
     GAIN_12|INPUT_MIC_GAIN_ENABLE,	/* Right Input Control */
@@ -172,7 +177,41 @@
     0,					/* upper record count */
     0					/* lower record count */
 };
+#else
+static int opti93x_init_values[] = {
+    ATTEN_12,
+    ATTEN_12,
+    GAIN_12 << 1,
+    GAIN_12 << 1,
+    GAIN_12 << 1,
+    GAIN_12 << 1,
+    CLOCK_XTAL1|FMT_PCM8,		/* Clock and Data Format */
+    SINGLE_DMA|AUTO_CAL_ENABLE,		/* Interface Config */
+    INTERRUPT_ENABLE,			/* Pin control */
+    0x00,				/* Test and Init */
+    0,				/* Misc control */
+    0,				/* Digital Mix Control */
+    0,					/* Upper base Count */
+    0,					/* Lower base Count */

+    /* exp. mode */
+    0x88,
+    0x88,
+    0x88,
+    0x88,
+    0x88,
+    0x88,
+    0x88,
+    0x88,
+    0,
+    0,
+    0,
+    0,
+    0,
+    0,					/* upper record count */
+    0					/* lower record count */
+};
+#endif

 __inline int ad_read __P((struct ad1848_softc *, int));
 __inline void ad_write __P((struct ad1848_softc *, int, int));
@@ -353,6 +392,7 @@
 	struct audio_params pparams, rparams;
 	int timeout;

+#if 0
 	/* Initialize the ad1848... */
 	for (i = 0; i < 0x10; i++) {
 		ad_write(sc, i, ad1848_init_values[i]);
@@ -372,6 +412,14 @@
 					timeout--;
 			}
 	}
+#else
+	for (i = 0; i < 0x20; i++) {
+		ad_write(sc, i, opti93x_init_values[i]);
+		timeout = 100000;
+		while (timeout > 0 && ad_read(sc, AD1848_IADDR) & SP_IN_INIT)
+			timeout--;
+	}
+#endif
 	ad1848_reset(sc);

 	pparams = audio_default;
@@ -381,8 +429,13 @@
 	/* Set default gains */
 	ad1848_set_rec_gain(sc, &vol_mid);
 	ad1848_set_channel_gain(sc, AD1848_DAC_CHANNEL, &vol_mid);
+#if 0
 	ad1848_set_channel_gain(sc, AD1848_MONITOR_CHANNEL, &vol_0);
 	ad1848_set_channel_gain(sc, AD1848_AUX1_CHANNEL, &vol_mid);	/* CD volume */
+#else
+	ad1848_set_channel_gain(sc, OPT93x_MASTER_CHANNEL, &vol_mid);
+	ad1848_set_channel_gain(sc, OPT93x_CD_CHANNEL, &vol_mid);
+#endif
 	if (sc->mode == 2) {
 		ad1848_set_channel_gain(sc, AD1848_AUX2_CHANNEL, &vol_mid); /* CD volume */
 		ad1848_set_channel_gain(sc, AD1848_LINE_CHANNEL, &vol_mid);
@@ -406,6 +459,7 @@
 	int  atten_bits;
 	int  atten_mask;
 } mixer_channel_info[] =
+#if 0
 {
   { SP_LEFT_AUX2_CONTROL, SP_RIGHT_AUX2_CONTROL, AUX_INPUT_ATTEN_BITS,
     AUX_INPUT_ATTEN_MASK },
@@ -418,7 +472,22 @@
   { CS_MONO_IO_CONTROL, 0, MONO_INPUT_ATTEN_BITS, MONO_INPUT_ATTEN_MASK },
   { SP_DIGITAL_MIX, 0, OUTPUT_ATTEN_BITS, MIX_ATTEN_MASK }
 };
-
+#else
+{
+  { OPT93x_LEFT_MIC_INPUT_CONTROL, OPT93x_RIGHT_MIC_INPUT_CONTROL,
+    AUX_INPUT_ATTEN_BITS, AUX_INPUT_ATTEN_MASK },
+  { OPT93x_LEFT_CD_INPUT_CONTROL, OPT93x_RIGHT_CD_INPUT_CONTROL,
+    AUX_INPUT_ATTEN_BITS, AUX_INPUT_ATTEN_MASK },
+  { SP_LEFT_OUTPUT_CONTROL, SP_RIGHT_OUTPUT_CONTROL,
+    OUTPUT_ATTEN_BITS, OUTPUT_ATTEN_MASK },
+  { OPT93x_LEFT_LINE_INPUT_CONTROL, OPT93x_RIGHT_LINE_INPUT_CONTROL,
+    LINE_INPUT_ATTEN_BITS, LINE_INPUT_ATTEN_MASK },
+    { CS_MONO_IO_CONTROL, 0, MONO_INPUT_ATTEN_BITS, MONO_INPUT_ATTEN_MASK }, /* NOT SERVED */
+  { SP_DIGITAL_MIX, 0, OUTPUT_ATTEN_BITS, MIX_ATTEN_MASK }, /* We must use MC register */
+  { OPT93x_LEFT_OUT_GAIN_CONTROL, OPT93x_RIGHT_OUT_GAIN_CONTROL,
+      0x3e, 0xc1 }
+};
+#endif
 /*
  *  This function doesn't set the mute flags but does use them.
  *  The mute flags reflect the mutes that have been applied by the user.
@@ -564,6 +633,10 @@

 	ad1848_mute_channel(sc, AD1848_AUX2_CHANNEL, mute ? MUTE_ALL : 0);
 	ad1848_mute_channel(sc, AD1848_AUX1_CHANNEL, mute ? MUTE_ALL : 0);
+#if 1
+	ad1848_mute_channel(sc, OPT93x_MASTER_CHANNEL, mute ? MUTE_ALL : 0);
+	ad1848_mute_channel(sc, 0, mute ? MUTE_ALL : 0);
+#endif
 }

 int
@@ -645,7 +718,10 @@
 			break;

 		if (dev < AD1848_AUX2_CHANNEL ||
+		    /*
 		    dev > AD1848_MONITOR_CHANNEL)
+		    */
+		    dev > OPT93x_MASTER_CHANNEL)
 			break;

 		if (cp->un.value.num_channels != 1 &&
@@ -720,7 +796,10 @@
 			break;

 		if (dev < AD1848_AUX2_CHANNEL ||
+		    /*
 		    dev > AD1848_MONITOR_CHANNEL)
+		    */
+		    dev > OPT93x_MASTER_CHANNEL)
 			break;

 		if (cp->un.value.num_channels != 1 &&
diff -ur /sys/dev/isa/ad1848_isa.c dev/isa/ad1848_isa.c
--- /sys/dev/isa/ad1848_isa.c	Mon Mar 22 23:54:01 1999
+++ dev/isa/ad1848_isa.c	Sun Sep 19 03:50:58 1999
@@ -298,7 +298,7 @@
 	 * fails with CS4231, AD1845, etc.
 	 */
 	ad_write(sc, SP_MISC_INFO, 0);	/* Mode2 = disabled */
-
+#if 0
 	for (i = 0; i < 16; i++)
 		if ((tmp1 = ad_read(sc, i)) != (tmp2 = ad_read(sc, i + 16))) {
 			if (i != SP_TEST_AND_INIT) {
@@ -306,7 +306,10 @@
 				goto bad;
 			}
 		}
-
+#else
+	/* fake */
+	i=0;
+#endif
 	/*
 	 * Try to switch the chip to mode2 (CS4231) by setting the MODE2 bit
 	 * The bit 0x80 is always 1 in CS4248, CS4231, and AD1845.
diff -ur /sys/dev/isa/files.isa dev/isa/files.isa
--- /sys/dev/isa/files.isa	Tue Mar 23 07:33:36 1999
+++ dev/isa/files.isa	Sun Sep 19 13:06:28 1999
@@ -295,11 +295,14 @@
 file	dev/isa/pss.c			pss needs-flag

 # Microsoft Windows Sound System
-device	wss: audio, isadma, ad1848, auconv
+device	wss { }: audio, isadma, ad1848, auconv, midibus
 file	dev/isa/wss.c			wss needs-flag

 attach	wss at isa with wss_isa
 file	dev/isa/wss_isa.c		wss_isa needs-flag

 # ESS Technology ES1887/ES888/ES1888
 device	ess { } : audio, isadma, mulaw, auconv, midibus
diff -ur /sys/dev/isa/madreg.h dev/isa/madreg.h
--- /sys/dev/isa/madreg.h	Tue Dec  8 23:26:57 1998
+++ dev/isa/madreg.h	Tue Sep 21 08:03:27 1999
@@ -65,6 +65,23 @@
 #define MC5_PORT	4
 #define MC6_PORT	5
 #define MC7_PORT	6
+#define MC8_PORT	7
+#define MC9_PORT	8
+#define MC10_PORT	9
+#define MC11_PORT	10
+#define MC12_PORT	11
+#define MC13_PORT	12
+#define MC14_PORT	13
+#define MC15_PORT	14
+#define MC16_PORT	15
+#define MC17_PORT	16
+#define MC18_PORT	17
+#define MC19_PORT	18
+#define MC20_PORT	19
+#define MC21_PORT	20
+#define MC22_PORT	21
+#define MC23_PORT	22

 #define MC1_NOCD	0x00
 #define MC1_JOYDISABLE	0x01
@@ -99,3 +104,5 @@
 #define MAD_LEN2 2
 #define MAD_REG3 0x388
 #define MAD_LEN3 4
+#define MAD_931_PASSWD_REG 0xf8d
+#define MAD_931_PASSWD_LEN 1
diff -ur /sys/dev/isa/wss.c dev/isa/wss.c
--- /sys/dev/isa/wss.c	Fri Feb 19 02:27:39 1999
+++ dev/isa/wss.c	Sat Jan 15 20:34:45 2000
@@ -54,13 +54,14 @@
 #include <dev/ic/cs4231reg.h>
 #include <dev/isa/ad1848var.h>
 #include <dev/isa/cs4231var.h>
+#include <dev/ic/opti93xreg.h>
 #include <dev/isa/wssreg.h>
 #include <dev/isa/wssvar.h>
 #include <dev/isa/madreg.h>

 #ifdef AUDIO_DEBUG
 #define DPRINTF(x)	if (wssdebug) printf x
 int	wssdebug = 0;
 #else
 #define DPRINTF(x)
 #endif
@@ -180,6 +181,7 @@
 }

 static ad1848_devmap_t mappings[] = {
+#if 0
 	{ WSS_MIC_IN_LVL, AD1848_KIND_LVL, AD1848_AUX2_CHANNEL },
 	{ WSS_LINE_IN_LVL, AD1848_KIND_LVL, AD1848_AUX1_CHANNEL },
 	{ WSS_DAC_LVL, AD1848_KIND_LVL, AD1848_DAC_CHANNEL },
@@ -190,6 +192,19 @@
 	{ WSS_MONITOR_MUTE, AD1848_KIND_MUTE, AD1848_MONO_CHANNEL },
 	{ WSS_REC_LVL, AD1848_KIND_RECORDGAIN, -1 },
 	{ WSS_RECORD_SOURCE, AD1848_KIND_RECORDSOURCE, -1}
+#else
+	{ WSS_MIC_IN_LVL, AD1848_KIND_LVL, OPT93x_MIC_CHANNEL },
+	{ WSS_LINE_IN_LVL, AD1848_KIND_LVL, OPT93x_CD_CHANNEL },
+	{ WSS_DAC_LVL, AD1848_KIND_LVL, AD1848_DAC_CHANNEL },
+	{ WSS_MONITOR_LVL, AD1848_KIND_LVL, OPT93x_MASTER_CHANNEL },
+	{ WSS_MIC_IN_MUTE, AD1848_KIND_MUTE, OPT93x_MIC_CHANNEL },
+	{ WSS_LINE_IN_MUTE, AD1848_KIND_MUTE, OPT93x_CD_CHANNEL },
+	{ WSS_DAC_MUTE, AD1848_KIND_MUTE, AD1848_DAC_CHANNEL },
+	{ WSS_MONITOR_MUTE, AD1848_KIND_MUTE, OPT93x_MASTER_CHANNEL },
+	{ WSS_REC_LVL, AD1848_KIND_RECORDGAIN, -1},  /* ??? */
+	{ WSS_RECORD_SOURCE, AD1848_KIND_RECORDSOURCE, -1} /* ??? */
+#endif
+
 };

 static int nummap = sizeof(mappings) / sizeof(mappings[0]);
@@ -410,8 +425,16 @@
 		panic("mad_read: Bad chip type=%d\n", sc->mad_chip_type);
 	}
 	s = splaudio();		/* don't want an interrupt between outb&inb */
-	bus_space_write_1(sc->sc_iot, sc->mad_ioh, MC_PASSWD_REG, pwd);
-	tmp = bus_space_read_1(sc->sc_iot, sc->mad_ioh, port);
+        if(sc->mad_chip_type !=MAD_82C931)
+        {
+  	  bus_space_write_1(sc->sc_iot, sc->mad_ioh, MC_PASSWD_REG, pwd);
+	  tmp = bus_space_read_1(sc->sc_iot, sc->mad_ioh, port);
+	} else {
+          bus_space_write_1(sc->sc_iot, sc->mad_931passwd_ioh, 0, pwd);
+	  bus_space_write_1(sc->sc_iot, sc->mad_ioh, 0, (port + 1) & 0xff);
+          bus_space_write_1(sc->sc_iot, sc->mad_931passwd_ioh, 0, pwd);
+	  tmp = bus_space_read_1(sc->sc_iot, sc->mad_ioh, 1);
+	}
 	splx(s);
 	return tmp;
 }
@@ -440,8 +463,16 @@
 		panic("mad_write: Bad chip type=%d\n", sc->mad_chip_type);
 	}
 	s = splaudio();
-	bus_space_write_1(sc->sc_iot, sc->mad_ioh, MC_PASSWD_REG, pwd);
-	bus_space_write_1(sc->sc_iot, sc->mad_ioh, port, value & 0xff);
+        if(sc->mad_chip_type !=MAD_82C931)
+        {
+	  bus_space_write_1(sc->sc_iot, sc->mad_ioh, MC_PASSWD_REG, pwd);
+	  bus_space_write_1(sc->sc_iot, sc->mad_ioh, port, value & 0xff);
+	} else {
+          bus_space_write_1(sc->sc_iot, sc->mad_931passwd_ioh, 0, pwd);
+	  bus_space_write_1(sc->sc_iot, sc->mad_ioh, 0, (port + 1) & 0xff);
+          bus_space_write_1(sc->sc_iot, sc->mad_931passwd_ioh, 0, pwd);
+	  bus_space_write_1(sc->sc_iot, sc->mad_ioh, 1, value & 0xff);
+	}
 	splx(s);
 }

@@ -460,22 +491,39 @@
 	joy = ac->sc_dev.dv_cfdata->cf_flags & 2 ? MC1_JOYDISABLE : 0;

 	/* enable WSS emulation at the I/O port */
-	mad_write(sc, MC1_PORT, M_WSS_PORT_SELECT(sc->mad_ioindex) | joy);
-	mad_write(sc, MC2_PORT, MC2_NO_CD_DRQ); /* disable CD */
-	mad_write(sc, MC3_PORT, 0xf0); /* Disable SB */
+        if (sc->mad_chip_type != MAD_82C931) {
+	  mad_write(sc, MC1_PORT, M_WSS_PORT_SELECT(sc->mad_ioindex) | joy);
+	  mad_write(sc, MC2_PORT, MC2_NO_CD_DRQ); /* disable CD */
+	  mad_write(sc, MC3_PORT, 0xf0); /* Disable SB */

-	cs4231_mode = 
+	  cs4231_mode = 
 		strncmp(ac->chip_name, "CS4248", 6) == 0 ||
 		strncmp(ac->chip_name, "CS4231", 6) == 0 ? 0x02 : 0;

-	if (sc->mad_chip_type == MAD_82C929) {
+	  if (sc->mad_chip_type == MAD_82C929) {
 		mad_write(sc, MC4_PORT, 0x92);
 		mad_write(sc, MC5_PORT, 0xA5 | cs4231_mode);
 		mad_write(sc, MC6_PORT, 0x03);	/* Disable MPU401 */
-	} else {
+	  } else {
 		mad_write(sc, MC4_PORT, 0x02);
 		mad_write(sc, MC5_PORT, 0x30 | cs4231_mode);
+	  }
+	} else {
+#if 0 /* BOGUS */
+	  mad_write(sc, MC9_PORT, 0x02);
+	  mad_write(sc, MC9_PORT, 0x00);
+
+	  mad_write(sc, MC6_PORT, 0x02);
+	  mad_write(sc, MC4_PORT, 0xd6);
+
+#if 1
+	  mad_write(sc, MC5_PORT, 0x28);
+#else
+	  mad_write(sc, MC5_PORT, 0x1c);
+#endif
+#endif /* BOGUS */
 	}
+

 #ifdef AUDIO_DEBUG
 	if (wssdebug) {
diff -ur /sys/dev/isa/wssvar.h dev/isa/wssvar.h
--- /sys/dev/isa/wssvar.h	Sat Feb 20 01:15:07 1999
+++ dev/isa/wssvar.h	Sun Sep 19 13:14:15 1999
@@ -71,6 +71,9 @@
 	int	mad_ioindex;
 	bus_space_handle_t mad_ioh;	/* MAD handle */
 	bus_space_handle_t mad_ioh1, mad_ioh2, mad_ioh3;
+	bus_space_handle_t mad_931passwd_ioh;
+
+        bus_space_handle_t sc_opl_ioh;
 };

 void	wssattach __P((struct wss_softc *));
diff -ur /sys/dev/isapnp/isapnpdevs dev/isapnp/isapnpdevs
--- /sys/dev/isapnp/isapnpdevs	Sat Apr 17 05:28:15 1999
+++ dev/isapnp/isapnpdevs	Thu Aug 12 17:29:49 1999
@@ -180,6 +180,7 @@
 /*
  * wss
  */
+devlogic	wss	OPT9310		2	OPTi Audio 16
 devlogic	wss	AZT0001		1	Aztech AZT2320 AUDIO
 devlogic	wss	CSC0000		0	Windows Sound System
 devlogic	wss	CSCA800		0	Terratec EWS64 CoDec
diff -ur /sys/dev/isapnp/isapnpdevs.c dev/isapnp/isapnpdevs.c
--- /sys/dev/isapnp/isapnpdevs.c	Sat Apr 17 05:28:42 1999
+++ dev/isapnp/isapnpdevs.c	Thu Aug 12 17:29:49 1999
@@ -1,4 +1,4 @@
-/*	$NetBSD: isapnpdevs.c,v 1.27.2.1 1999/04/16 20:28:42 augustss Exp $	*/
+/*	$NetBSD$	*/

 /*
  * THIS FILE AUTOMATICALLY GENERATED.  DO NOT EDIT.
@@ -241,13 +241,14 @@

 /* Microsoft Sound System */
 static const struct isapnp_matchinfo isapnp_wss_devlogic[] = {
+	{"OPT9310", 2},	/* OPTi Audio 16 */
 	{"AZT0001", 1},	/* Aztech AZT2320 AUDIO */
 	{"CSC0000", 0},	/* Windows Sound System */
 	{"CSCA800", 0},	/* Terratec EWS64 CoDec */
 	{"ASB1611", 0},	/* AdLib NSC 16 PNP */
 };
 const struct isapnp_devinfo isapnp_wss_devinfo = {
-	isapnp_wss_devlogic, 4,
+	isapnp_wss_devlogic, 5,
 	NULL, 0,
 };

diff -ur /sys/dev/isapnp/wss_isapnp.c dev/isapnp/wss_isapnp.c
--- /sys/dev/isapnp/wss_isapnp.c	Mon Mar 22 23:29:14 1999
+++ dev/isapnp/wss_isapnp.c	Mon Sep 27 08:26:23 1999
@@ -62,6 +62,9 @@
 int	wss_isapnp_match __P((struct device *, struct cfdata *, void *));
 void	wss_isapnp_attach __P((struct device *, struct device *, void *));

+static void mad_isapnp_probe __P((struct wss_softc *, struct isapnp_attach_args *));
+static void mad_isapnp_attach __P((struct wss_softc *, u_int32_t ));
+
 struct cfattach wss_isapnp_ca = {
 	sizeof(struct wss_softc), wss_isapnp_match, wss_isapnp_attach
 };
@@ -71,6 +74,186 @@
  * Probe / attach routines.
  */

+static void
+mad_isapnp_probe(sc, ipa)
+    struct wss_softc *sc;
+    struct isapnp_attach_args *ipa;
+
+{
+  bus_space_tag_t iot;
+  bus_space_handle_t ioh;
+
+  struct isapnp_region *r;
+#if 0
+  int error;
+#endif
+  static int valid_ports[M_WSS_NPORTS] = 
+      { M_WSS_PORT0, M_WSS_PORT1, M_WSS_PORT2, M_WSS_PORT3 };
+
+  int i;
+
+  iot = ipa->ipa_iot;
+  r   = ipa->ipa_io;
+  ioh = r->h;
+
+#if 0 /* config port is already collect. */
+  /* old mss have 4 bytes before... */
+  {
+        if (r[0].length == 0)
+                return;
+
+#ifdef _KERNEL
+        bus_space_unmap(iot, r[0].h, r[0].length);
+#endif
+    }
+
+  r[0].base -= 4;
+  r[0].length += 4;
+#ifdef _KERNEL
+  error = bus_space_map(iot, r[0].base, r[0].length, 0, &r[0].h);
+#endif			
+  if(error)
+    {
+      printf("MAD_92C931 mapping failed.\n");
+    }
+#endif
+  /* XXX */
+  /* mad mc port is located within [0xe1e, 0xe0f],
+   [0xe1e, 0xe1f],
+   to [0xffe, 0xfff] */
+  {
+    u_int32_t base;
+    u_int32_t base_offset;
+    u_char    base_bit;
+
+    base=0xe0e;
+    do {
+
+      if((r[3].base <= base) && (r[3].base+r[3].length - 1 >= base + 1))
+	goto mad_ok;
+
+      base += 0x10;
+    } while(base < 0xfff);
+
+      printf("MAD_92C931: alloc mc port failed.\n");
+      goto mad_bad0;
+
+  mad_ok:
+    base_offset = base - r[3].base;
+    base_bit = ((base >> 4) & 0x1f);
+
+    bus_space_map(iot, 0xf8d, 1, 0, &sc->mad_931passwd_ioh);
+#if 0
+    {
+      /* Dump port */
+
+      int tmp;
+
+      bus_space_write_1(iot, sc->mad_931passwd_ioh, 0, M_PASSWD_931);
+      tmp = bus_space_read_1(iot, sc->mad_931passwd_ioh, 0);
+      printf("MC 0xf8d: %x\n", tmp);
+      printf("MC port base address %x\n", (( 7 * 512 + 15) | (( tmp & 0x1f) << 4 )));
+    }
+    /* Init MC port */
+    bus_space_write_1(iot, sc->mad_931passwd_ioh, 0, M_PASSWD_931);
+    bus_space_write_1(iot, sc->mad_931passwd_ioh, 0, base_bit);
+#endif
+    bus_space_subregion(iot, r[3].h, base_offset, 2, &sc->mad_ioh);
+  }
+  sc->mad_ioh1 = r[2].h;
+
+  bus_space_subregion(iot, r[1].h, 0, MAD_LEN2, &sc->mad_ioh2);
+  bus_space_subregion(iot, r[1].h, 8, MAD_LEN3, &sc->mad_ioh3);
+
+  /* Set the WSS address. */
+  for (i = 0; i < M_WSS_NPORTS; i++)
+    if (valid_ports[i] == r[0].base - 4)
+      break;
+  if (i >= M_WSS_NPORTS) {		/* Not a valid port */
+    printf("mad: Bad WSS base address 0x%x\n", r[0].base);
+    goto mad_bad;
+  }
+    sc->mad_ioindex = i;
+
+    sc->mad_chip_type = MAD_82C931;
+#if 0
+    printf("MC port:\n");
+    printf("01 02 03 04 05 06 07 08 09 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26\n");
+    for ( i = 0; i < 26 ; i++) {
+      int tmp;
+
+      tmp = mad_read(sc, i);
+      printf("%2.2X ", tmp);
+    }
+    printf("\n");
+#endif
+#if 1 /* AAA */
+#if 0
+    mad_write(sc, MC1_PORT, sc->mad_ioindex << 4 | MC1_JOYDISABLE);
+    mad_write(sc, MC2_PORT, 0x03); /* ? */
+#endif
+    /* fifo empty, OPL3, audio enable, SB3.2 */
+    mad_write(sc, MC4_PORT, 0xd6);
+    mad_write(sc, MC6_PORT, 0x02);  /* MCIR6: mss enable, sb disable */
+    mad_write(sc, MC5_PORT, 0x28);  /* MCIR5: codec in exp */
+#endif /* AAA */
+#if 0
+    printf("MC port:\n");
+    printf("01 02 03 04 05 06 07 08 09 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26\n");
+    for ( i = 0; i < 26 ; i++) {
+      int tmp;
+
+      tmp = mad_read(sc, i);
+      printf("%2.2X ", tmp);
+    }
+    printf("\n");
+#endif
+#if 0
+  DELAY(250);
+  printf("WSSBASE: %x\n", bus_space_read_1(iot, r[0].h, 0));
+#endif
+
+  return;
+
+mad_bad:
+    bus_space_unmap(iot, sc->mad_ioh3, MAD_LEN3);
+#if 0
+mad_bad3:
+#endif
+    bus_space_unmap(iot, sc->mad_ioh2, MAD_LEN2);
+#if 0
+mad_bad2:
+#endif
+    bus_space_unmap(iot, sc->mad_ioh1, MAD_LEN1);
+#if 0
+mad_bad1:
+#endif
+    bus_space_unmap(iot, sc->mad_ioh, MAD_NPORT);
+mad_bad0:
+    sc->mad_chip_type = MAD_NONE;
+}
+
+/* XXX */
+static void
+mad_isapnp_attach(sc, base)
+    struct wss_softc *sc;
+    u_int32_t base;
+{
+  bus_space_handle_t ioh;
+
+  static int interrupt_bits[12] = {
+    -1, -1, -1, -1, -1, 0x208, -1, 0x08, -1, 0x10, 0x18, 0x20
+    };
+#if 1 /* XXX : recdrq assumed */
+  static u_char dma_bits[4] = {5, 6, 0, 7};
+#endif
+
+  bus_space_map(sc->sc_iot, base - 4, 1, 0, &ioh);
+  bus_space_write_1(sc->sc_iot, ioh, 0, (interrupt_bits[sc->wss_irq] | dma_bits[sc->wss_playdrq]));
+  bus_space_unmap(sc->sc_iot, ioh, 1);
+  return;
+}
+
 /*
  * Probe for the WSS hardware.
  */
@@ -83,7 +266,7 @@
 	int pri, variant;

 	pri = isapnp_devmatch(aux, &isapnp_wss_devinfo, &variant);
-	if (pri && variant > 1)
+	if (pri && variant > 2)
 		pri = 0;
 	return (pri);
 }
@@ -106,16 +289,37 @@

 	printf("\n");

+#if 0 
+        {
+	  /* Dump port */
+	  bus_space_tag_t iot;
+	  int tmp;
+	  iot = ipa->ipa_iot;
+	  bus_space_map(iot, 0xf8d, 1, 0, &sc->mad_931passwd_ioh);
+
+	  tmp = bus_space_read_1(iot, sc->mad_931passwd_ioh, 0);
+	  printf("MC without passwd 0xf8d: %x\n", tmp);
+
+	  bus_space_write_1(iot, sc->mad_931passwd_ioh, 0, M_PASSWD_931);
+	  tmp = bus_space_read_1(iot, sc->mad_931passwd_ioh, 0);
+	  printf("MC 0xf8d: %x\n", tmp);
+	  printf("MC port base address %x\n", (( 7 * 512 + 15) | (( tmp & 0x1f) << 4 )));
+
+	  bus_space_unmap(iot, sc->mad_931passwd_ioh, 1);
+	}
+#endif
 	if (!isapnp_devmatch(aux, &isapnp_wss_devinfo, &variant)) {
 		printf("%s: match failed?\n", self->dv_xname);
 		return;
+
 	}
-			
+#if 1
+	/* ????? */		
 	if (isapnp_config(ipa->ipa_iot, ipa->ipa_memt, ipa)) {
 		printf("%s: error in region allocation\n", self->dv_xname);
 		return;
 	}
-
+#endif
 	switch (variant) {
 	case 1:
 		/* We have to put the chip into `WSS mode'. */
@@ -142,13 +346,17 @@
        		sc->sc_ioh = ipa->ipa_io[2].h;
 		break;

+	case 2:
+	  mad_isapnp_probe(sc, ipa);
+
 	default:
 		sc->sc_iot = ipa->ipa_iot;
 		sc->sc_ioh = ipa->ipa_io[0].h;
 		break;
 	}

-	sc->mad_chip_type = MAD_NONE;
+	if (variant != 2)
+	  sc->mad_chip_type = MAD_NONE;

 	/* Set up AD1848 I/O handle. */
 	ac->sc_iot = sc->sc_iot;
@@ -170,6 +378,8 @@

 	printf("%s: %s %s", self->dv_xname, ipa->ipa_devident,
 	    ipa->ipa_devclass);
+
+        mad_isapnp_attach(sc, ipa->ipa_io[0].base);

 	wssattach(sc);
 }
--- /dev/null	Sat Jan 15 21:00:26 2000
+++ dev/ic/opti93xreg.h	Sat Jan 15 20:21:30 2000
@@ -0,0 +1,39 @@
+#define OPT93x_LEFT_MIXER_OUT_CONTROL 0
+#define OPT93x_RIGHT_MIXER_OUT_CONTROL 1
+#define OPT93x_LEFT_CD_INPUT_CONTROL 2   /* AUX2 */
+#define OPT93x_RIGHT_CD_INPUT_CONTROL 3
+#define OPT93x_LEFT_FM_INPUT_CONTROL 4   /* LINE??? */
+#define OPT93x_RIGHT_FM_INPUT_CONTROL 5
+#define OPT93x_LEFT_DAC_INPUT_CONTROL 6  
+#define OPT93x_RIGHT_DAC_INPUT_CONTROL 7
+#define OPT93x_PLAYBACK_DATA_FORMAT 8
+#define OPT93x_INTERFACE_CONFIG	9
+#define OPT93x_PIN_CONTROL		10
+#define OPT93x_TEST_AND_INIT	11
+#define OPT93x_MISC_INFO		12
+#define OPT93x_RESERVED_13 13
+#define OPT93x_PLAYBACK_UPPER_BASE_COUNT	14
+#define OPT93x_PLAYBACK_LOWER_BASE_COUNT	15
+
+
+/* exp. mode */
+#define OPT93x_LEFT_AUX_LINE_INPUT_CONTROL 16
+#define OPT93x_RIGHT_AUX_LINE_INPUT_CONTROL 17
+#define OPT93x_LEFT_LINE_INPUT_CONTROL 18
+#define OPT93x_RIGHT_LINE_INPUT_CONTROL 19
+#define OPT93x_LEFT_MIC_INPUT_CONTROL 20
+#define OPT93x_RIGHT_MIC_INPUT_CONTROL 21
+#define OPT93x_LEFT_OUT_GAIN_CONTROL 22    /* MAIN Volume */
+#define OPT93x_RIGHT_OUT_GAIN_CONTROL 23
+#define OPT93x_RESERVED_24 24
+#define OPT93x_RESERVED_25 25
+#define OPT93x_RESERVED_26 26
+#define OPT93x_RESERVED_27 27
+#define OPT93x_CAPTURE_DATA_FORMAT 28
+#define OPT93x_RESERVED_29 29
+#define OPT93x_CAPTURE_UPPER_BASE_COUNT 30
+#define OPT93x_CAPTURE_LOWER_BASE_COUNT 31
+
+#define OPT93x_MIC_CHANNEL 0
+#define OPT93x_CD_CHANNEL 1
+#define OPT93x_MASTER_CHANNEL 6

>Release-Note:
>Audit-Trail:
>Unformatted:

NetBSD Home
NetBSD PR Database Search

(Contact us) $NetBSD: query-full-pr,v 1.39 2013/11/01 18:47:49 spz Exp $
$NetBSD: gnats_config.sh,v 1.8 2006/05/07 09:23:38 tsutsui Exp $
Copyright © 1994-2007 The NetBSD Foundation, Inc. ALL RIGHTS RESERVED.