Subject: Re: is audio fully working for anyone on T30?
To: Jonathan Stone <jonathan@dsg.stanford.edu>
From: Greg Troxel <gdt@ir.bbn.com>
List: port-i386
Date: 03/08/2005 19:15:01
This is a patch against FreeBSD 4 (so run through
freebsd4-to-netbsd2.99(8) before applying :-), and made audio work way
better on a 600E (2645-4AU I think).  I still use one for testing, but
haven't needed audio.  This patch is mostly the work of Bill
Chiarchiaro, and some by me.  It was helpful to read the datasheet.

This patch avoids PCI attachment, but I think that works around
FreeBSD issue that doesn't affect NetBSD.  The real issue is the
extended register set which needs indirect writing.  The mic gain is
moved there, and the set needs to be saved/restored on suspend.


Index: conf/files
===================================================================
RCS file: /FREEBSD-CVS/src/sys/conf/files,v
retrieving revision 1.340.2.106
diff -u -r1.340.2.106 files
--- conf/files	2002/06/24 14:36:36	1.340.2.106
+++ conf/files	2003/01/10 13:04:20
@@ -1,4 +1,4 @@
-# $FreeBSD$
+# $FreeBSD: src/sys/conf/files,v 1.340.2.106 2002/06/24 14:36:36 fanf Exp $
 #
 # The long compile-with and dependency lines are required because of
 # limitations in config: backslash-newline doesn't work in strings, and
@@ -1189,8 +1189,7 @@
 dev/sound/pci/cmi.c	optional pcm pci
 dev/sound/pci/cs4281.c	optional pcm pci
 dev/sound/pci/csa.c	optional csa pci
-dev/sound/pci/csa.c	optional pcm pci
-dev/sound/pci/csapcm.c	optional pcm pci
+dev/sound/pci/csapcm.c	optional csa pcm pci
 dev/sound/pci/ds1.c	optional pcm pci
 dev/sound/pci/emu10k1.c	optional pcm pci
 dev/sound/pci/es137x.c	optional pcm pci
Index: dev/sound/isa/mss.c
===================================================================
RCS file: /FREEBSD-CVS/src/sys/dev/sound/isa/mss.c,v
retrieving revision 1.48.2.10
diff -u -r1.48.2.10 mss.c
--- dev/sound/isa/mss.c	2002/04/22 15:49:30	1.48.2.10
+++ dev/sound/isa/mss.c	2003/01/10 13:04:30
@@ -29,7 +29,7 @@
 
 #include <dev/sound/pcm/sound.h>
 
-SND_DECLARE_FILE("$FreeBSD$");
+SND_DECLARE_FILE("$FreeBSD: src/sys/dev/sound/isa/mss.c,v 1.48.2.10 2002/04/22 15:49:30 cg Exp $");
 
 /* board-specific include files */
 #include <dev/sound/isa/mss.h>
@@ -41,6 +41,8 @@
 #define MSS_DEFAULT_BUFSZ (4096)
 #define	abs(x)	(((x) < 0) ? -(x) : (x))
 #define MSS_INDEXED_REGS 0x20
+#define MSS_EXTENDED_REGS 0x20
+#define MSS_EXTENDED_REGS_OFFSET 0x20
 #define OPL_INDEXED_REGS 0x19
 
 struct mss_info;
@@ -68,7 +70,7 @@
     bus_dma_tag_t    parent_dmat;
     void	    *lock;
 
-    char mss_indexed_regs[MSS_INDEXED_REGS];
+    char mss_indxd_extnd_regs[MSS_EXTENDED_REGS_OFFSET + MSS_EXTENDED_REGS];
     char opl_indexed_regs[OPL_INDEXED_REGS];
     int bd_id;      /* used to hold board-id info, eg. sb version,
 		     * mss codec type, etc. etc.
@@ -744,8 +746,19 @@
 		conf_wr(mss, OPL3SAx_DMACONF, FULL_DUPLEX(mss)? 0xa9 : 0x8b);
 		break;
  	}
-    	if (FULL_DUPLEX(mss) && mss->bd_id != MD_OPTI931)
-    		ad_write(mss, 12, ad_read(mss, 12) | 0x40); /* mode 2 */
+
+	  tmp = ad_read(mss, 12) & 0xff;
+	  ad_write(mss, 12, 0x60);
+
+	  if (FULL_DUPLEX(mss) && mss->bd_id != MD_OPTI931) {
+	    if (1) { /* change to mss->bd_id == MD_CS4239 */
+	      ad_write(mss, 12, ad_read(mss, 12) | 0x60); /* mode 3 */
+	      ad_write(mss, 34, ad_read(mss, 34) | 0x20); /* mic boost */
+	      ad_write(mss, 35, ad_read(mss, 35) | 0x20); /* mic boost */
+	    }
+	    else
+	      ad_write(mss, 12, ad_read(mss, 12) | 0x40); /* mode 2 */
+	  }
 	ad_enter_MCE(mss);
     	ad_write(mss, 9, FULL_DUPLEX(mss)? 0 : 4);
     	ad_leave_MCE(mss);
@@ -834,9 +847,29 @@
     	int             x;
 
     	ad_wait_init(mss, 201000);
-    	x = io_rd(mss, MSS_INDEX) & ~MSS_IDXMASK;
-    	io_wr(mss, MSS_INDEX, (u_char)(reg & MSS_IDXMASK) | x);
-    	x = io_rd(mss, MSS_IDATA);
+	if (reg <= 31)
+	  {
+	    x = io_rd(mss, MSS_INDEX) & ~MSS_IDXMASK;
+	    io_wr(mss, MSS_INDEX, (u_char)(reg & MSS_IDXMASK) | x);
+	    x = io_rd(mss, MSS_IDATA);
+	  }
+	else
+        {
+	  x = io_rd(mss, MSS_INDEX) & ~MSS_IDXMASK;
+	  io_wr(mss, MSS_INDEX, (u_char)(23 & MSS_IDXMASK) | x);
+
+	  x = io_rd(mss, MSS_IDATA) & 0x3;
+	  io_wr(mss, MSS_IDATA,
+		(u_char)((reg & 0xf)  << 4 |
+			 (reg & 0x10) >> 2 |
+			 I23_XRAE) |
+		x);
+
+	  x = io_rd(mss, MSS_IDATA);
+
+	  io_wr(mss, MSS_INDEX, io_rd(mss, MSS_INDEX));
+	}
+
 	/* printf("ad_read %d, %x\n", reg, x); */
     	return x;
 }
@@ -848,9 +881,29 @@
 
 	/* printf("ad_write %d, %x\n", reg, data); */
     	ad_wait_init(mss, 1002000);
-    	x = io_rd(mss, MSS_INDEX) & ~MSS_IDXMASK;
-    	io_wr(mss, MSS_INDEX, (u_char)(reg & MSS_IDXMASK) | x);
-    	io_wr(mss, MSS_IDATA, data);
+
+	if (reg <= 31)
+	{
+	  x = io_rd(mss, MSS_INDEX) & ~MSS_IDXMASK;
+	  io_wr(mss, MSS_INDEX, (u_char)(reg & MSS_IDXMASK) | x);
+	  io_wr(mss, MSS_IDATA, data);
+	}
+	else
+	{
+	  x = io_rd(mss, MSS_INDEX) & ~MSS_IDXMASK;
+	  io_wr(mss, MSS_INDEX, (u_char)(23 & MSS_IDXMASK) | x);
+
+	  x = io_rd(mss, MSS_IDATA) & 0x3;
+	  io_wr(mss, MSS_IDATA,
+		(u_char)((reg & 0xf)  << 4 |
+			 (reg & 0x10) >> 2 |
+			 I23_XRAE) |
+		x);
+
+	  io_wr(mss, MSS_IDATA, data);
+
+	  io_wr(mss, MSS_INDEX, io_rd(mss, MSS_INDEX));
+	}
 }
 
 static void
@@ -1807,15 +1860,23 @@
 
     	mss = pcm_getdevinfo(dev);
 
-    	if (mss->bd_id == MD_YM0020)
-    	{
-		/* This works on a Toshiba Libretto 100CT. */
-		for (i = 0; i < MSS_INDEXED_REGS; i++)
-    			ad_write(mss, i, mss->mss_indexed_regs[i]);
-		for (i = 0; i < OPL_INDEXED_REGS; i++)
-    			conf_wr(mss, i, mss->opl_indexed_regs[i]);
-		mss_intr(mss);
+    	switch (mss->bd_id)
+	{
+	case MD_CS42XX: /* perhaps should be MD_CS4239 */
+	  for (i = 0; i < MSS_EXTENDED_REGS_OFFSET + MSS_EXTENDED_REGS; i++)
+	    ad_write(mss, i, mss->mss_indxd_extnd_regs[i]);
+	  break;
+
+	case MD_YM0020:
+	  /* This works on a Toshiba Libretto 100CT. */
+	  for (i = 0; i < MSS_INDEXED_REGS; i++)
+	    ad_write(mss, i, mss->mss_indxd_extnd_regs[i]);
+	  for (i = 0; i < OPL_INDEXED_REGS; i++)
+	    conf_wr(mss, i, mss->opl_indexed_regs[i]);
+	  mss_intr(mss);
+	  break;
     	}
+
     	return 0;
 
 }
@@ -1837,16 +1898,24 @@
 
     	mss = pcm_getdevinfo(dev);
 
-    	if(mss->bd_id == MD_YM0020)
-    	{
-		/* this stops playback. */
-		conf_wr(mss, 0x12, 0x0c);
-		for(i = 0; i < MSS_INDEXED_REGS; i++)
-    			mss->mss_indexed_regs[i] = ad_read(mss, i);
-		for(i = 0; i < OPL_INDEXED_REGS; i++)
-    			mss->opl_indexed_regs[i] = conf_rd(mss, i);
-		mss->opl_indexed_regs[0x12] = 0x0;
-    	}
+	switch (mss->bd_id)
+	{
+	case MD_CS42XX: /* perhaps should be MD_CS4239 */
+	  for(i = 0; i < MSS_EXTENDED_REGS_OFFSET + MSS_INDEXED_REGS; i++)
+	    mss->mss_indxd_extnd_regs[i] = ad_read(mss, i);
+	  break;
+
+	case MD_YM0020:
+	    /* this stops playback. */
+	    conf_wr(mss, 0x12, 0x0c);
+	    for(i = 0; i < MSS_INDEXED_REGS; i++)
+	      mss->mss_indxd_extnd_regs[i] = ad_read(mss, i);
+	    for(i = 0; i < OPL_INDEXED_REGS; i++)
+	      mss->opl_indexed_regs[i] = conf_rd(mss, i);
+	    mss->opl_indexed_regs[0x12] = 0x0;
+	    break;
+	}
+
     	return 0;
 }
 
Index: dev/sound/isa/mss.h
===================================================================
RCS file: /FREEBSD-CVS/src/sys/dev/sound/isa/mss.h,v
retrieving revision 1.7.2.6
diff -u -r1.7.2.6 mss.h
--- dev/sound/isa/mss.h	2002/04/22 15:49:31	1.7.2.6
+++ dev/sound/isa/mss.h	2003/01/10 13:04:31
@@ -117,6 +117,12 @@
 #define	I9_CEN		0x02	/* capture enable */
 
 /*
+ * register I23 -- extended register access.
+ */
+
+#define I23_XRAE	0x08	/* extended register access enable */
+
+/*
  * values used in bd_flags
  */
 #define	BD_F_MCE_BIT	0x0001
@@ -199,7 +205,8 @@
 MIX_ENT(SOUND_MIXER_PCM,	 6, 1, 0, 6,	 7, 1, 0, 6),
 MIX_ENT(SOUND_MIXER_SPEAKER,	26, 1, 0, 4,	 0, 0, 0, 0),
 MIX_ENT(SOUND_MIXER_LINE,	18, 1, 0, 5,	19, 1, 0, 5),
-MIX_ENT(SOUND_MIXER_MIC,	 0, 0, 5, 1,	 1, 0, 5, 1),
+/*MIX_ENT(SOUND_MIXER_MIC,	 0, 0, 5, 1,	 1, 0, 5, 1),*/
+MIX_ENT(SOUND_MIXER_MIC,	34, 1, 0, 5,	35, 1, 0, 5),
 #ifdef PC98	/* PC98's cd-audio is assigned to AUX#1 */
 MIX_ENT(SOUND_MIXER_CD,	 	 2, 1, 0, 5,	 3, 1, 0, 5),
 #else		/* AT386's cd-audio is assigned to AUX#2 */
@@ -303,7 +310,7 @@
  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  * SUCH DAMAGE.
  *
- * $FreeBSD$
+ * $FreeBSD: src/sys/dev/sound/isa/mss.h,v 1.7.2.6 2002/04/22 15:49:31 cg Exp $
  */
 
 /*
Index: dev/sound/pcm/mixer.c
===================================================================
RCS file: /FREEBSD-CVS/src/sys/dev/sound/pcm/mixer.c,v
retrieving revision 1.4.2.8
diff -u -r1.4.2.8 mixer.c
--- dev/sound/pcm/mixer.c	2002/04/22 15:49:36	1.4.2.8
+++ dev/sound/pcm/mixer.c	2003/01/10 13:04:32
@@ -28,7 +28,7 @@
 
 #include "mixer_if.h"
 
-SND_DECLARE_FILE("$FreeBSD$");
+SND_DECLARE_FILE("$FreeBSD: src/sys/dev/sound/pcm/mixer.c,v 1.4.2.8 2002/04/22 15:49:36 cg Exp $");
 
 MALLOC_DEFINE(M_MIXER, "mixer", "mixer");
 
@@ -390,6 +390,35 @@
 }
 
 /* ----------------------------------------------------------------------- */
+
+#if 0
+void
+change_bits(mixer_tab *t, u_char *regval, int dev, int chn, int newval)
+{
+    	u_char mask;
+    	int shift;
+
+    	DEB(printf("ch_bits dev %d ch %d val %d old 0x%02x "
+		"r %d p %d bit %d off %d\n",
+		dev, chn, newval, *regval,
+		(*t)[dev][chn].regno, (*t)[dev][chn].polarity,
+		(*t)[dev][chn].nbits, (*t)[dev][chn].bitoffs ) );
+
+	printf("mixer: dev = %d    chn = %d    newval = %d\n",
+	       dev, chn, newval);
+
+    	if ( (*t)[dev][chn].polarity == 1)	/* reverse */
+		newval = 100 - newval ;
+
+    	mask = (1 << (*t)[dev][chn].nbits) - 1;
+    	newval = (int) ((newval * mask) + 50) / 100; /* Scale it */
+    	shift = (*t)[dev][chn].bitoffs /*- (*t)[dev][LEFT_CHN].nbits + 1*/;
+
+    	*regval &= ~(mask << shift);        /* Filter out the previous value */
+    	*regval |= (newval & mask) << shift;        /* Set the new value */
+	printf("mixer: *regval = 0x%02x\n", *regval);
+}
+#endif
 
 static int
 mixer_open(dev_t i_dev, int flags, int mode, struct proc *p)
Index: net/if.c
===================================================================
RCS file: /FREEBSD-CVS/src/sys/net/if.c,v
retrieving revision 1.85.2.18
diff -u -r1.85.2.18 if.c
--- net/if.c	2002/04/28 05:40:25	1.85.2.18
+++ net/if.c	2003/01/10 13:04:48
@@ -31,7 +31,7 @@
  * SUCH DAMAGE.
  *
  *	@(#)if.c	8.3 (Berkeley) 1/4/94
- * $FreeBSD$
+ * $FreeBSD: src/sys/net/if.c,v 1.85.2.18 2002/04/28 05:40:25 suz Exp $
  */
 
 #include "opt_compat.h"
@@ -1112,7 +1112,7 @@
 	case SIOCSLIFPHYADDR:
         case SIOCSIFMEDIA:
 	case SIOCSIFGENERIC:
-		error = suser(p);
+		error = (cmd == SIOCSIFGENERIC) ? 0 : suser(p);
 		if (error)
 			return (error);
 		if (ifp->if_ioctl == 0)