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)