Skip site navigation (1)Skip section navigation (2)
Date:      Fri, 20 Mar 1998 18:14:52 +0100 (MET)
From:      Luigi Rizzo <luigi@labinfo.iet.unipi.it>
To:        luigi@labinfo.iet.unipi.it (Luigi Rizzo)
Cc:        multimedia@FreeBSD.ORG
Subject:   patch for Vibra16X -- test please!
Message-ID:  <199803201714.SAA05208@labinfo.iet.unipi.it>

next in thread | raw e-mail | index | archive | help
[forgive me for the crosspost but I'm trying to get some feedback
quickly... since this might go into -stable and the deadline is
close...]

By popular demand, enclosed is a small patch to hopefully add
PARTIAL Vibra16X support for playback (there is also some still
non-functional code for the ESS -- don't worry about that bu i
prefer not to handcraft the patchfile). This is mostly derived from
code contributed by Torsten Ackemann.

The diff is against snd980215 which is essentially what is now in
-current and -stable. The modified files are only sb_dsp.c and
sbcard.h

Note that, assuming this code works at all:

 * it might affect plain SB16 support, so I'd like to have feedback from
   someone with the SB16 (it should still work fine);
 * it only works in playback; we haven't figured out yet how
   to tell capture from playback interrupts. And I have not
   been successful in getting documentation from Creative or Realtek
   (the latter make a Vibra16X clone).
 * you might have to add the PnP vend_id of your card near the
   end of sb_dsp.c -- there is a comment marked with VIBRA16X in this patch
   in the point where you should make the addition.

As usual, feedback is not only welcome but absolutely necessay
since I don't have a Vibra16X or clone. I need to know both if it
works and if it not works.  Do not forget to give details about
your card (e.g. brand, PnP vendor ID)

	cheers
	luigi


diff -ubwr snd/sb_dsp.c /sys/i386/isa/snd/sb_dsp.c
--- snd/sb_dsp.c	Tue Jan 27 21:01:49 1998
+++ /sys/i386/isa/snd/sb_dsp.c	Fri Mar 20 19:32:52 1998
@@ -275,9 +275,12 @@
      * SB < 4.0 is half duplex and has only 1 bit for int source,
      * so we fake it. SB 4.x (SB16) has the int source in a separate
      * register.
+     * The Vibra16X has separate flags for 8 and 16 bit transfers, but
+     * I have no idea how to tell capture from playback interrupts...
      */
+#define PLAIN_SB16(x) ( ( (x) & (BD_F_SB16|BD_F_SB16X) ) == BD_F_SB16)
 again:
-    if (d->bd_flags & BD_F_SB16) {
+    if (PLAIN_SB16(d->bd_flags)) {
 	c = sb_getmixer(io_base, IRQ_STAT);
 	/* this tells us if the source is 8-bit or 16-bit dma. We
 	 * have to check the io channel to map it to read or write...
@@ -302,7 +305,7 @@
 	if ( d->dbuf_out.dl )
 	    dsp_wrintr(d);
 	else {
-	    if (d->bd_flags & BD_F_SB16)
+	    if (PLAIN_SB16(d->bd_flags))
 	       printf("WARNING: wrintr but write DMA inactive!\n");
 	}
     }
@@ -310,7 +313,7 @@
 	if ( d->dbuf_in.dl )
 	    dsp_rdintr(d);
 	else {
-	    if (d->bd_flags & BD_F_SB16)
+	    if (PLAIN_SB16(d->bd_flags))
 	       printf("WARNING: rdintr but read DMA inactive!\n");
 	}
     }
@@ -353,7 +356,7 @@
 	else
 	    d->flags &= ~SND_F_XLAT8 ;
 
-	if (d->bd_flags & BD_F_SB16) {
+	if (PLAIN_SB16(d->bd_flags)) {
 	    u_char c, c1 ;
 
 	    /* the SB16 can do full duplex using one 16-bit channel
@@ -392,6 +395,29 @@
 		d->dbuf_in.chan = d->dbuf_out.chan;
 		d->dbuf_out.chan = c ;
 	    }
+	} else if (d->bd_flags & BD_F_ESS) {
+	    u_char c ;
+	    if (d->play_fmt == 0) {
+		/* initialize for record */
+		static u_char cmd[] = {
+		    0x51,0xd0,0x71,0xf4,0x51,0x98,0x71,0xbc
+		};
+		ess_write(d->io_base, 0xb8, 0x0e);
+		c = ( ess_read(d->io_base, 0xa8) & 0xfc ) | 1 ;
+		if (d->flags & SND_F_STEREO)
+		    c++ ;
+		ess_write(d->io_base, 0xa8, c);
+		ess_write(d->io_base, 0xb9, 2); /* 4bytes/transfer */
+		/*
+		 * set format in b6, b7
+		 */
+	    } else {
+		/* initialize for play */
+		static u_char cmd[] = {
+		    0x80,0x51,0xd0,0x00,0x71,0xf4,
+		    0x80,0x51,0x98,0x00,0x71,0xbc
+		};
+	    }
 	}
 	reset_dbuf(& (d->dbuf_in), SND_CHAN_RD );
 	reset_dbuf(& (d->dbuf_out), SND_CHAN_WR );
@@ -406,7 +432,10 @@
 	     * is assigned. This means that if the application
 	     * tries to use a bad format, the sound will not be nice.
 	     */
-	    if ( b->chan > 4 ) {
+	    if ( b->chan > 4
+		 || (rd && d->rec_fmt == AFMT_S16_LE)
+		 || (!rd && d->play_fmt == AFMT_S16_LE)
+	       ) {
 		c = DSP_F16_AUTO | DSP_F16_FIFO_ON | DSP_DMA16 ;
 		c1 = DSP_F16_SIGNED ;
 		l /= 2 ;
@@ -455,7 +484,10 @@
     case SND_CB_STOP :
 	{
 	    int cmd = DSP_CMD_DMAPAUSE_8 ; /* default: halt 8 bit chan */
-	    if ( d->bd_flags & BD_F_SB16 && b->chan > 4 )
+	    if ( b->chan > 4
+		 || (rd && d->rec_fmt == AFMT_S16_LE)
+		 || (!rd && d->play_fmt == AFMT_S16_LE)
+	       )
 		cmd = DSP_CMD_DMAPAUSE_16 ;
 	    if (d->bd_flags & BD_F_HISPEED) {
 		sb_reset_dsp(d->io_base);
@@ -618,7 +650,7 @@
 		    printf("ESS1868 (rev %d)\n", rev);
 		else
 		    printf("ESS688 (rev %d)\n", rev);
-		d->audio_fmt |= AFMT_S16_LE; /* in fact it is U16_LE */
+		/* d->audio_fmt |= AFMT_S16_LE; */ /* not yet... */
 		break ; /* XXX */
 	    } else {
 		printf("Unknown card 0x%x 0x%x -- hope it is SBPRO\n",
@@ -661,6 +693,14 @@
 
 /*
  * Common code for the midi and pcm functions
+ *
+ * sb_cmd write a single byte to the CMD port.
+ * sb_cmd2 write a CMD + 1 byte arg
+ * sb_cmd3 write a CMD + 2 byte arg
+ * sb_get_byte returns a single byte from the DSP data port
+ *
+ * ess_write is actually sb_cmd2
+ * ess_read access ext. regs via sb_cmd(0xc0, reg) followed by sb_get_byte
  */
 
 int
@@ -726,9 +766,9 @@
     u_long   flags;
     
     flags = spltty();
-    outb(io_base + 4, (u_char) (port & 0xff));   /* Select register */
+    outb(io_base + SB_MIX_ADDR, (u_char) (port & 0xff));   /* Select register */
     DELAY(10);
-    val = inb(io_base + 5);
+    val = inb(io_base + SB_MIX_DATA);
     DELAY(10);
     splx(flags);
     
@@ -748,6 +788,19 @@
     return 0xffff;
 }
 
+int
+ess_write(int io_base, u_char reg, int val)
+{
+    return sb_cmd2(io_base, reg, val);
+}
+
+int
+ess_read(int io_base, u_char reg)
+{
+    if (!sb_cmd(io_base, 0xc0) || !sb_cmd(io_base, reg) )
+	return 0xffff ;
+    return sb_get_byte(io_base);
+}
 
 
 /*
@@ -786,17 +839,21 @@
      */
     if (d->bd_flags & BD_F_ESS) {
 	int t;
-	RANGE (speed, 4000, 48000);
+	RANGE (speed, 5000, 49000);
 	if (speed > 22000) {
 	    t = (795500 + speed / 2) / speed;
 	    speed = (795500 + t / 2) / t ;
-	    t = ( 256 - (795500 + speed / 2) / speed ) | 0x80 ;
+	    t = (256 - t ) | 0x80 ;
 	} else {
 	    t = (397700 + speed / 2) / speed;
 	    speed = (397700 + t / 2) / t ;
-	    t = 128 - (397700 + speed / 2) / speed ;
+	    t = 128 - t ;
 	}
-	sb_cmd2(d->io_base, 0xa1, t); /* set time constant */
+	ess_write(d->io_base, 0xa1, t); /* set time constant */
+	d->play_speed = d->rec_speed = speed ;
+	speed = (speed * 9 ) / 20 ;
+	t = 256-7160000/(speed*82);
+	ess_write(d->io_base,0xa2,t);
 	return speed ;
     }
 
@@ -1154,6 +1211,7 @@
  * A driver for some SB16pnp and compatibles...
  *
  * Avance Asound 100 -- 0x01009305
+ * Avance Logic ALS100+ -- 0x10019305
  * xxx               -- 0x2b008c0e
  *
  */
@@ -1187,6 +1245,8 @@
 	s = "SB16 PnP";
     else if (vend_id == 0x01009305)  
         s = "Avance Asound 100" ;
+    else if (vend_id == 0x10009305)
+        s = "Avance Logic 100+" ;
     if (s) {
 	struct pnp_cinfo d; 
 	read_pnp_parms(&d, 0); 
@@ -1224,6 +1284,12 @@
     pcm_info[dev->id_unit] = tmp_d;
     snddev_last_probed->probe(dev); /* not really necessary but doesn't harm */
     
+    if (vend_id == 0x10009305) {
+	/*
+	 * VIBRA16X please add here the vend_id for other vibra16X cards...
+	 */
+	pcm_info[dev->id_unit].bd_flags |= BD_F_SB16X ;
+    }
     pcmattach(dev); 
 }
 #endif /* NPNP */    
Only in /sys/i386/isa/snd: sb_dsp.c.v16
diff -ubwr snd/sbcard.h /sys/i386/isa/snd/sbcard.h
--- snd/sbcard.h	Fri Jan 16 19:03:44 1998
+++ /sys/i386/isa/snd/sbcard.h	Thu Mar 12 09:40:16 1998
@@ -19,9 +19,9 @@
 #define DSP_DATA_AVAIL	(io_base + 0xE)
 #define DSP_DATA_AVL16	(io_base + 0xF)
 
+#define SB_MIX_ADDR	0x4
+#define SB_MIX_DATA	0x5
 #if 0
-#define MIXER_ADDR	(io_base + 0x4)
-#define MIXER_DATA	(io_base + 0x5)
 #define OPL3_LEFT	(io_base + 0x0)
 #define OPL3_RIGHT	(io_base + 0x2)
 #define OPL3_BOTH	(io_base + 0x8)
@@ -138,7 +138,7 @@
 #define	BD_F_MIX_CT1745	0x0030	/* CT1745		*/
 
 #define	BD_F_SB16	0x0100	/* this is a SB16 */
-#define	BD_F_NOREC	0x0200	/* recording not supported on this board */
+#define	BD_F_SB16X	0x0200	/* this is a vibra16X or clone */
 #define	BD_F_MIDIBUSY	0x0400	/* midi busy */
 #define	BD_F_ESS	0x0800	/* this is an ESS chip */
 
diff -ubwr snd/sound.c /sys/i386/isa/snd/sound.c
--- snd/sound.c	Fri Feb 13 15:33:08 1998
+++ /sys/i386/isa/snd/sound.c	Sat Mar 14 23:11:35 1998
@@ -717,7 +717,7 @@
 	    snd_chan_param *p = (snd_chan_param *)arg;
 	    d->play_speed = p->play_rate;
 	    d->rec_speed = p->play_rate; /* XXX one speed allowed */
-	    if (p->play_format & SND_F_STEREO)
+	    if (p->play_format & AFMT_STEREO)
 		d->flags |= SND_F_STEREO ;
 	    else
 		d->flags &= ~SND_F_STEREO ;

To Unsubscribe: send mail to majordomo@FreeBSD.org
with "unsubscribe freebsd-stable" in the body of the message



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?199803201714.SAA05208>