make the vibra16x work for playback at least, record is untested

This commit is contained in:
Cameron Grant 1999-12-18 22:21:47 +00:00
parent 4dc39f110c
commit 354398891a
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=54791
5 changed files with 75 additions and 45 deletions

View File

@ -648,9 +648,9 @@ sb_start(struct sb_chinfo *ch)
int stereo = (ch->fmt & AFMT_STEREO)? 1 : 0;
int l = ch->buffer->dl;
int dh = ch->buffer->chan > 3;
u_char i1, i2 = 0;
u_char i1, i2;
if (b16) l >>= 1;
if (b16 || dh) l >>= 1;
l--;
if (play) sb_cmd(sb, DSP_CMD_SPKON);
if (sb->bd_flags & BD_F_SB16) {
@ -812,14 +812,18 @@ sbchan_init(void *devinfo, snd_dbuf *b, pcm_channel *c, int dir)
{
struct sb_info *sb = devinfo;
struct sb_chinfo *ch = (dir == PCMDIR_PLAY)? &sb->pch : &sb->rch;
int dch, dl, dh;
ch->parent = sb;
ch->channel = c;
ch->buffer = b;
ch->buffer->bufsize = DSP_BUFFSIZE;
if (chn_allocbuf(ch->buffer, sb->parent_dmat) == -1) return NULL;
ch->buffer->chan = (dir == PCMDIR_PLAY)? rman_get_start(sb->drq2)
: rman_get_start(sb->drq1);
dch = (dir == PCMDIR_PLAY)? 1 : 0;
if (sb->bd_flags & BD_F_SB16X) dch = !dch;
dl = rman_get_start(sb->drq1);
if (sb->drq2) dh = rman_get_start(sb->drq2); else dh = dl;
ch->buffer->chan = dch? dh : dl;
return ch;
}
@ -1078,7 +1082,7 @@ static int
sbsbc_probe(device_t dev)
{
char buf[64];
u_int32_t func, ver, r;
u_int32_t func, ver, r, f;
/* The parent device has already been probed. */
r = BUS_READ_IVAR(device_get_parent(dev), dev, 0, &func);
@ -1086,8 +1090,10 @@ sbsbc_probe(device_t dev)
return (ENXIO);
r = BUS_READ_IVAR(device_get_parent(dev), dev, 1, &ver);
f = (ver & 0xffff0000) >> 16;
ver &= 0x0000ffff;
snprintf(buf, sizeof buf, "SB DSP %d.%02d", ver >> 8, ver & 0xff);
snprintf(buf, sizeof buf, "SB DSP %d.%02d%s", ver >> 8, ver & 0xff,
(f & BD_F_ESS)? " (ESS mode)" : "");
device_set_desc_copy(dev, buf);
return 0;

View File

@ -123,8 +123,10 @@
*/
#define BD_F_HISPEED 0x0001 /* doing high speed ... */
#if 0
#define BD_F_JAZZ16 0x0002 /* jazz16 detected */
#define BD_F_JAZZ16_2 0x0004 /* jazz16 type 2 */
#endif
#define BD_F_DUP_MIDI 0x0008 /* duplex midi */
@ -135,16 +137,19 @@
#define BD_F_SB16 0x0100 /* this is a SB16 */
#define BD_F_SB16X 0x0200 /* this is a vibra16X or clone */
#if 0
#define BD_F_MIDIBUSY 0x0400 /* midi busy */
#endif
#define BD_F_ESS 0x0800 /* this is an ESS chip */
/*
* on some SB16 cards, at times I swap DMA channels. Remember this
* so that they can be restored later.
*/
#if 0
#define BD_F_SWAPPED 0x1000 /* have swapped DMA channels */
#endif
#define BD_F_DMARUN 0x2000
#define BD_F_DMARUN2 0x4000
#define BD_F_DUPLEX 0x8000
/*
* Mixer registers of SB Pro

View File

@ -648,9 +648,9 @@ sb_start(struct sb_chinfo *ch)
int stereo = (ch->fmt & AFMT_STEREO)? 1 : 0;
int l = ch->buffer->dl;
int dh = ch->buffer->chan > 3;
u_char i1, i2 = 0;
u_char i1, i2;
if (b16) l >>= 1;
if (b16 || dh) l >>= 1;
l--;
if (play) sb_cmd(sb, DSP_CMD_SPKON);
if (sb->bd_flags & BD_F_SB16) {
@ -812,14 +812,18 @@ sbchan_init(void *devinfo, snd_dbuf *b, pcm_channel *c, int dir)
{
struct sb_info *sb = devinfo;
struct sb_chinfo *ch = (dir == PCMDIR_PLAY)? &sb->pch : &sb->rch;
int dch, dl, dh;
ch->parent = sb;
ch->channel = c;
ch->buffer = b;
ch->buffer->bufsize = DSP_BUFFSIZE;
if (chn_allocbuf(ch->buffer, sb->parent_dmat) == -1) return NULL;
ch->buffer->chan = (dir == PCMDIR_PLAY)? rman_get_start(sb->drq2)
: rman_get_start(sb->drq1);
dch = (dir == PCMDIR_PLAY)? 1 : 0;
if (sb->bd_flags & BD_F_SB16X) dch = !dch;
dl = rman_get_start(sb->drq1);
if (sb->drq2) dh = rman_get_start(sb->drq2); else dh = dl;
ch->buffer->chan = dch? dh : dl;
return ch;
}
@ -1078,7 +1082,7 @@ static int
sbsbc_probe(device_t dev)
{
char buf[64];
u_int32_t func, ver, r;
u_int32_t func, ver, r, f;
/* The parent device has already been probed. */
r = BUS_READ_IVAR(device_get_parent(dev), dev, 0, &func);
@ -1086,8 +1090,10 @@ sbsbc_probe(device_t dev)
return (ENXIO);
r = BUS_READ_IVAR(device_get_parent(dev), dev, 1, &ver);
f = (ver & 0xffff0000) >> 16;
ver &= 0x0000ffff;
snprintf(buf, sizeof buf, "SB DSP %d.%02d", ver >> 8, ver & 0xff);
snprintf(buf, sizeof buf, "SB DSP %d.%02d%s", ver >> 8, ver & 0xff,
(f & BD_F_ESS)? " (ESS mode)" : "");
device_set_desc_copy(dev, buf);
return 0;

View File

@ -648,9 +648,9 @@ sb_start(struct sb_chinfo *ch)
int stereo = (ch->fmt & AFMT_STEREO)? 1 : 0;
int l = ch->buffer->dl;
int dh = ch->buffer->chan > 3;
u_char i1, i2 = 0;
u_char i1, i2;
if (b16) l >>= 1;
if (b16 || dh) l >>= 1;
l--;
if (play) sb_cmd(sb, DSP_CMD_SPKON);
if (sb->bd_flags & BD_F_SB16) {
@ -812,14 +812,18 @@ sbchan_init(void *devinfo, snd_dbuf *b, pcm_channel *c, int dir)
{
struct sb_info *sb = devinfo;
struct sb_chinfo *ch = (dir == PCMDIR_PLAY)? &sb->pch : &sb->rch;
int dch, dl, dh;
ch->parent = sb;
ch->channel = c;
ch->buffer = b;
ch->buffer->bufsize = DSP_BUFFSIZE;
if (chn_allocbuf(ch->buffer, sb->parent_dmat) == -1) return NULL;
ch->buffer->chan = (dir == PCMDIR_PLAY)? rman_get_start(sb->drq2)
: rman_get_start(sb->drq1);
dch = (dir == PCMDIR_PLAY)? 1 : 0;
if (sb->bd_flags & BD_F_SB16X) dch = !dch;
dl = rman_get_start(sb->drq1);
if (sb->drq2) dh = rman_get_start(sb->drq2); else dh = dl;
ch->buffer->chan = dch? dh : dl;
return ch;
}
@ -1078,7 +1082,7 @@ static int
sbsbc_probe(device_t dev)
{
char buf[64];
u_int32_t func, ver, r;
u_int32_t func, ver, r, f;
/* The parent device has already been probed. */
r = BUS_READ_IVAR(device_get_parent(dev), dev, 0, &func);
@ -1086,8 +1090,10 @@ sbsbc_probe(device_t dev)
return (ENXIO);
r = BUS_READ_IVAR(device_get_parent(dev), dev, 1, &ver);
f = (ver & 0xffff0000) >> 16;
ver &= 0x0000ffff;
snprintf(buf, sizeof buf, "SB DSP %d.%02d", ver >> 8, ver & 0xff);
snprintf(buf, sizeof buf, "SB DSP %d.%02d%s", ver >> 8, ver & 0xff,
(f & BD_F_ESS)? " (ESS mode)" : "");
device_set_desc_copy(dev, buf);
return 0;

View File

@ -241,12 +241,13 @@ bad: return s? 0 : ENXIO;
static int
sbc_attach(device_t dev)
{
char *err = NULL;
struct sbc_softc *scp;
struct sndcard_func *func;
device_t child;
u_int32_t logical_id = isa_get_logicalid(dev);
int flags = device_get_flags(dev);
int f = 0, dh = -1, dl = -1;
int f, dh, dl, x, irq;
if (!logical_id && (flags & DV_F_DUAL_DMA)) {
bus_set_resource(dev, SYS_RES_DRQ, 1,
@ -256,11 +257,15 @@ sbc_attach(device_t dev)
scp = device_get_softc(dev);
bzero(scp, sizeof(*scp));
scp->dev = dev;
err = "alloc_resource";
if (alloc_resource(scp)) goto bad;
err = "sb_reset_dsp";
if (sb_reset_dsp(scp->io[0])) goto bad;
err = "sb_identify_board";
scp->bd_ver = sb_identify_board(scp->io[0]) & 0x00000fff;
if (scp->bd_ver == 0) goto bad;
f = 0;
switch ((scp->bd_ver & 0x0f00) >> 8) {
case 1: /* old sound blaster has nothing... */
break;
@ -279,33 +284,34 @@ sbc_attach(device_t dev)
case 4:
f |= BD_F_SB16 | BD_F_MIX_CT1745;
if (scp->drq[0]) dl = rman_get_start(scp->drq[0]);
if (scp->drq[0]) dl = rman_get_start(scp->drq[0]); else dl = -1;
if (scp->drq[1]) dh = rman_get_start(scp->drq[1]); else dh = dl;
if (dh != dl) f |= BD_F_DUPLEX;
if (dh < dl) {
struct resource *r;
r = scp->drq[0];
scp->drq[0] = scp->drq[1];
scp->drq[1] = r;
dl = rman_get_start(scp->drq[0]);
dh = rman_get_start(scp->drq[1]);
}
if (!logical_id) {
/* soft irq/dma configuration */
int x = -1, irq = rman_get_start(scp->irq);
if (irq == 5) x = 2;
else if (irq == 7) x = 4;
else if (irq == 9) x = 1;
else if (irq == 10) x = 8;
if (x == -1) device_printf(dev,
"bad irq %d (5/7/9/10 valid)\n",
irq);
else sb_setmixer(scp->io[0], IRQ_NR, x);
sb_setmixer(scp->io[0], DMA_NR, (1 << dh) | (1 << dl));
device_printf(dev, "setting non-pnp card to irq %d, drq %d", irq, dl);
if (dl != dh) printf(", %d", dh);
printf("\n");
if (dh < dl) {
struct resource *r;
r = scp->drq[0];
scp->drq[0] = scp->drq[1];
scp->drq[1] = r;
dl = rman_get_start(scp->drq[0]);
dh = rman_get_start(scp->drq[1]);
}
}
/* soft irq/dma configuration */
x = -1;
irq = rman_get_start(scp->irq);
if (irq == 5) x = 2;
else if (irq == 7) x = 4;
else if (irq == 9) x = 1;
else if (irq == 10) x = 8;
if (x == -1) {
err = "bad irq (5/7/9/10 valid)";
goto bad;
}
else sb_setmixer(scp->io[0], IRQ_NR, x);
sb_setmixer(scp->io[0], DMA_NR, (1 << dh) | (1 << dl));
device_printf(dev, "setting card to irq %d, drq %d", irq, dl);
if (dl != dh) printf(", %d", dh);
printf("\n");
break;
}
@ -348,7 +354,8 @@ sbc_attach(device_t dev)
return (0);
bad: release_resource(scp);
bad: if (err) device_printf(dev, "%s\n", err);
release_resource(scp);
return (ENXIO);
}