From owner-freebsd-multimedia Fri Mar 20 10:54:11 1998 Return-Path: Received: (from majordom@localhost) by hub.freebsd.org (8.8.8/8.8.8) id KAA26771 for freebsd-multimedia-outgoing; Fri, 20 Mar 1998 10:54:11 -0800 (PST) (envelope-from owner-freebsd-multimedia@FreeBSD.ORG) Received: from labinfo.iet.unipi.it (labinfo.iet.unipi.it [131.114.9.5]) by hub.freebsd.org (8.8.8/8.8.8) with SMTP id KAA26169; Fri, 20 Mar 1998 10:52:08 -0800 (PST) (envelope-from luigi@labinfo.iet.unipi.it) Received: from localhost (luigi@localhost) by labinfo.iet.unipi.it (8.6.5/8.6.5) id SAA05208; Fri, 20 Mar 1998 18:14:52 +0100 From: Luigi Rizzo Message-Id: <199803201714.SAA05208@labinfo.iet.unipi.it> Subject: patch for Vibra16X -- test please! To: luigi@labinfo.iet.unipi.it (Luigi Rizzo) Date: Fri, 20 Mar 1998 18:14:52 +0100 (MET) Cc: multimedia@FreeBSD.ORG X-Mailer: ELM [version 2.4 PL23] Content-Type: text Sender: owner-freebsd-multimedia@FreeBSD.ORG Precedence: bulk X-Loop: FreeBSD.org [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-multimedia" in the body of the message