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>