Date: Sat, 21 Mar 1998 21:36:26 +0100 (MET) From: Luigi Rizzo <luigi@labinfo.iet.unipi.it> To: luigi@labinfo.iet.unipi.it (Luigi Rizzo) Cc: multimedia@FreeBSD.ORG Subject: Re: patch for Vibra16X -- test please! Message-ID: <199803212036.VAA06977@labinfo.iet.unipi.it> In-Reply-To: <199803201714.SAA05208@labinfo.iet.unipi.it> from "Luigi Rizzo" at Mar 20, 98 06:14:33 pm
next in thread | previous in thread | raw e-mail | index | archive | help
ok, the last Vibra16X patches i sent out contained a couple of
minor errors, plus now i have added the Vibra16X PnP ID so you should
have nothing tricky to do. Can you people try this one instead...
again this is a diff against -stable/-current/snd980215
cheers
luigi
diff -ubwr /usr/ports/distfiles/snd/sb_dsp.c ./sb_dsp.c
--- /usr/ports/distfiles/snd/sb_dsp.c Tue Jan 27 21:01:49 1998
+++ ./sb_dsp.c Sat Mar 21 23:07:05 1998
@@ -275,13 +275,17 @@
* 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) {
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...
*/
+ if ( (d->bd_flags & BD_F_SB16X) == 0 ) {
reason = 0 ;
if ( c & 1 ) { /* 8-bit dma */
if (d->dbuf_out.chan < 4)
@@ -296,13 +300,14 @@
reason |= 2;
}
}
+ }
/* XXX previous location of ack... */
DEB(printf("sbintr, flags 0x%08lx reason %d\n", d->flags, reason));
if ( reason & 1 ) { /* possibly a write interrupt */
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 +315,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 +358,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 +397,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 +434,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 +486,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 +652,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 +695,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 +768,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 +790,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 +841,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 +1213,7 @@
* A driver for some SB16pnp and compatibles...
*
* Avance Asound 100 -- 0x01009305
+ * Avance Logic ALS100+ -- 0x10019305
* xxx -- 0x2b008c0e
*
*/
@@ -1182,11 +1242,16 @@
* Reported values are:
* SB16 Value PnP: 0x2b008c0e
* SB AWExx PnP: 0x39008c0e 0x9d008c0e 0xc3008c0e
+ * Vibra16X: 0xf0008c0e
*/
- if ( (vend_id & 0xffffff) == (0x9d008c0e & 0xffffff) )
+ if (vend_id == 0xf0008c0e)
+ s = "Vibra16X" ;
+ else if ( (vend_id & 0xffffff) == (0x9d008c0e & 0xffffff) )
s = "SB16 PnP";
else if (vend_id == 0x01009305)
s = "Avance Asound 100" ;
+ else if (vend_id == 0x10019305)
+ s = "Avance Logic 100+" ; /* Vibra16X-class */
if (s) {
struct pnp_cinfo d;
read_pnp_parms(&d, 0);
@@ -1224,6 +1289,12 @@
pcm_info[dev->id_unit] = tmp_d;
snddev_last_probed->probe(dev); /* not really necessary but doesn't harm */
+ if (vend_id == 0x10019305 || vend_id == 0xf0008c0e) {
+ /*
+ * XXX please add here the vend_id for other vibra16X cards...
+ */
+ pcm_info[dev->id_unit].bd_flags |= BD_F_SB16X ;
+ }
pcmattach(dev);
}
#endif /* NPNP */
diff -ubwr /usr/ports/distfiles/snd/sbcard.h ./sbcard.h
--- /usr/ports/distfiles/snd/sbcard.h Fri Jan 16 19:03:44 1998
+++ ./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 */
To Unsubscribe: send mail to majordomo@FreeBSD.org
with "unsubscribe freebsd-multimedia" in the body of the message
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?199803212036.VAA06977>
