aboutsummaryrefslogtreecommitdiff
path: root/sys/dev/sound
diff options
context:
space:
mode:
authorBrian Somers <brian@FreeBSD.org>1998-12-10 18:36:10 +0000
committerBrian Somers <brian@FreeBSD.org>1998-12-10 18:36:10 +0000
commitdb21d4f4fc6f5865c16397f84cea6c40629d3086 (patch)
treef6ef39048b68da6ae065d2e6c06a31b081ec9c27 /sys/dev/sound
parent6ab0ab275d344e9019d16aba31163cffdd528828 (diff)
Notes
Diffstat (limited to 'sys/dev/sound')
-rw-r--r--sys/dev/sound/isa/sb.c133
-rw-r--r--sys/dev/sound/isa/sb.h30
-rw-r--r--sys/dev/sound/isa/sb16.c133
-rw-r--r--sys/dev/sound/isa/sb8.c133
4 files changed, 294 insertions, 135 deletions
diff --git a/sys/dev/sound/isa/sb.c b/sys/dev/sound/isa/sb.c
index 06599ec7d010a..4bd5825664398 100644
--- a/sys/dev/sound/isa/sb.c
+++ b/sys/dev/sound/isa/sb.c
@@ -337,7 +337,7 @@ again:
/*
* the sb16 might have multiple sources etc.
*/
- if (d->bd_flags & BD_F_SB16 && (c & 3) )
+ if ((d->bd_flags & BD_F_SB16) && (c & 3))
goto again;
}
@@ -428,29 +428,63 @@ sb_callback(snddev_info *d, int reason)
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
- };
- }
+ }
+ else if (d->bd_flags & BD_F_ESS) {
+ u_char c;
+
+ DEB(printf("SND_CB_INIT, play_fmt == 0x%x, rec_fmt == 0x%x\n",
+ (int) d->play_fmt, (int) d->rec_fmt));
+
+ /* autoinit DMA mode */
+ if (d->play_fmt)
+ ess_write(d->io_base, 0xb8, 0x04);
+ else
+ ess_write(d->io_base, 0xb8, 0x0e);
+
+ c = (ess_read(d->io_base, 0xa8) & ~0x03) | 0x01;
+ if ((d->flags & SND_F_STEREO) == 0)
+ c++;
+ ess_write(d->io_base, 0xa8, c); /* select mono/stereo */
+ ess_write(d->io_base, 0xb9, 2); /* demand 4 bytes/transfer */
+
+ switch (d->play_fmt ? d->play_fmt : d->rec_fmt) {
+ case AFMT_S16_LE:
+ if (d->flags & SND_F_STEREO) {
+ /* 16 bit stereo */
+ if (d->play_fmt)
+ ess_write(d->io_base, 0xb6, 0x00);
+ ess_write(d->io_base, 0xb7, 0x71);
+ ess_write(d->io_base, 0xb7, 0xbc);
+ }
+ else {
+ /* 16 bit mono */
+ if (d->play_fmt)
+ ess_write(d->io_base, 0xb6, 0x00);
+ ess_write(d->io_base, 0xb7, 0x71);
+ ess_write(d->io_base, 0xb7, 0xf4);
+ }
+ break;
+ case AFMT_U8:
+ if (d->flags & SND_F_STEREO) {
+ /* 8 bit stereo */
+ if (d->play_fmt)
+ ess_write(d->io_base, 0xb6, 0x80);
+ ess_write(d->io_base, 0xb7, 0x51);
+ ess_write(d->io_base, 0xb7, 0x98);
+ }
+ else {
+ /* 8 bit mono */
+ if (d->play_fmt)
+ ess_write(d->io_base, 0xb6, 0x80);
+ ess_write(d->io_base, 0xb7, 0x51);
+ ess_write(d->io_base, 0xb7, 0xd0);
+ }
+ break;
+ }
+ ess_write(d->io_base, 0xb1,
+ ess_read(d->io_base, 0xb1) | 0x50);
+ ess_write(d->io_base, 0xb2,
+ ess_read(d->io_base, 0xb1) | 0x50);
}
reset_dbuf(& (d->dbuf_in), SND_CHAN_RD );
reset_dbuf(& (d->dbuf_out), SND_CHAN_WR );
@@ -512,10 +546,18 @@ sb_callback(snddev_info *d, int reason)
sb_cmd(d->io_base, c );
sb_cmd3(d->io_base, c1 , l - 1) ;
} else if (d->bd_flags & BD_F_ESS) {
- /* XXX this code is still incomplete */
- sb_cmd2(d->io_base, 0xb8, rd ? 4 : 0xe ) ; /* auto dma */
- sb_cmd2(d->io_base, 0xa8, d->flags & SND_F_STEREO ? 1 : 2) ;
- sb_cmd2(d->io_base, 0xb9, 2) ; /* demand dma */
+ u_long fmt = rd ? d->rec_fmt : d->play_fmt;
+
+ DEB(printf("SND_CB_START: %s (%d)\n", rd ? "rd" : "wr", l));
+ if (fmt == AFMT_S16_LE)
+ l >>= 1;
+ l--;
+ if (!rd)
+ sb_cmd(d->io_base, DSP_CMD_SPKON);
+ ess_write(d->io_base, 0xa4, l);
+ ess_write(d->io_base, 0xa5, l >> 8);
+ ess_write(d->io_base, 0xb8,
+ ess_read(d->io_base, 0xb8) | (rd ? 0x0f : 0x05));
} else { /* SBPro -- stereo not supported */
u_char c ;
if (!rd)
@@ -546,6 +588,7 @@ sb_callback(snddev_info *d, int reason)
case SND_CB_STOP :
{
int cmd = DSP_CMD_DMAPAUSE_8 ; /* default: halt 8 bit chan */
+ DEB(printf("SND_CB_XXX: reason 0x%x\n", reason));
if ( b->chan > 4
|| (rd && d->rec_fmt == AFMT_S16_LE)
|| (!rd && d->play_fmt == AFMT_S16_LE)
@@ -722,14 +765,22 @@ sb_dsp_init(snddev_info *d, struct isa_device *dev)
/* the ESS488 can be treated as an SBPRO */
printf("ESS488 (rev %d)\n", ess_minor & 0x0f);
break ;
- } else if (ess_major == 0x68 && (ess_minor & 0xf0) == 0x80) {
- int rev = ess_minor & 0xf ;
- if ( rev >= 8 )
- printf("ESS1868 (rev %d)\n", rev);
- else
- printf("ESS688 (rev %d)\n", rev);
- /* d->audio_fmt |= AFMT_S16_LE; */ /* not yet... */
- break ; /* XXX */
+ }
+ else if (ess_major == 0x68 && (ess_minor & 0xf0) == 0x80) {
+ u_char cfg;
+ u_char bits;
+ int rev = ess_minor & 0xf;
+
+ if (rev >= 8)
+ printf("ESS1868 (rev %d)\n", rev);
+ else
+ printf("ESS688 (rev %d)\n", rev);
+ d->bd_flags |= BD_F_ESS;
+ d->audio_fmt |= AFMT_S16_LE;
+
+ /* enable extended ESS mode */
+ sb_cmd(d->io_base, 0xc6);
+ break;
} else {
printf("Unknown card 0x%x 0x%x -- hope it is SBPRO\n",
ess_major, ess_minor);
@@ -831,9 +882,9 @@ sb_setmixer(int io_base, u_int port, u_int value)
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);
- outb(io_base + 5, (u_char) (value & 0xff));
+ outb(io_base + SB_MIX_DATA, (u_char) (value & 0xff));
DELAY(10);
splx(flags);
}
@@ -1210,10 +1261,12 @@ ess1868_attach(u_long csn, u_long vend_id, char *name,
dev->id_drq = d.drq[0] ; /* primary dma */
dev->id_irq = (1 << d.irq[0] ) ;
- dev->id_intr = pcmintr ;
+ dev->id_intr = (inthand2_t *)pcmintr ;
dev->id_flags = 0 /* DV_F_DUAL_DMA | (d.drq[1] ) */;
+#if 0
snddev_last_probed->probe(dev); /* not really necessary but doesn't harm */
+#endif
pcmattach(dev);
}
@@ -1291,7 +1344,7 @@ sb16pnp_attach(u_long csn, u_long vend_id, char *name,
dev->id_drq = d.drq[0] ; /* primary dma */
dev->id_irq = (1 << d.irq[0] ) ;
- dev->id_intr = pcmintr ;
+ dev->id_intr = (inthand2_t *)pcmintr ;
dev->id_flags = DV_F_DUAL_DMA | (d.drq[1] ) ;
pcm_info[dev->id_unit] = tmp_d; /* pcm_info[] will be reinitialized after */
diff --git a/sys/dev/sound/isa/sb.h b/sys/dev/sound/isa/sb.h
index 92ec966107911..481719961a78e 100644
--- a/sys/dev/sound/isa/sb.h
+++ b/sys/dev/sound/isa/sb.h
@@ -264,15 +264,15 @@ static u_char sb16_recmasks_L[SOUND_MIXER_NRDEVICES];
static u_char sb16_recmasks_R[SOUND_MIXER_NRDEVICES];
#else /* __SB_MIXER_C__ defined */
mixer_tab sbpro_mix = {
- PMIX_ENT(SOUND_MIXER_VOLUME, 0x22, 7, 4, 0x22, 3, 4),
+ PMIX_ENT(SOUND_MIXER_VOLUME, 0x22, 4, 4, 0x22, 0, 4),
PMIX_ENT(SOUND_MIXER_BASS, 0x00, 0, 0, 0x00, 0, 0),
PMIX_ENT(SOUND_MIXER_TREBLE, 0x00, 0, 0, 0x00, 0, 0),
- PMIX_ENT(SOUND_MIXER_SYNTH, 0x26, 7, 4, 0x26, 3, 4),
- PMIX_ENT(SOUND_MIXER_PCM, 0x04, 7, 4, 0x04, 3, 4),
+ PMIX_ENT(SOUND_MIXER_SYNTH, 0x26, 4, 4, 0x26, 0, 4),
+ PMIX_ENT(SOUND_MIXER_PCM, 0x04, 4, 4, 0x04, 0, 4),
PMIX_ENT(SOUND_MIXER_SPEAKER, 0x00, 0, 0, 0x00, 0, 0),
- PMIX_ENT(SOUND_MIXER_LINE, 0x2e, 7, 4, 0x2e, 3, 4),
- PMIX_ENT(SOUND_MIXER_MIC, 0x0a, 2, 3, 0x00, 0, 0),
- PMIX_ENT(SOUND_MIXER_CD, 0x28, 7, 4, 0x28, 3, 4),
+ PMIX_ENT(SOUND_MIXER_LINE, 0x2e, 4, 4, 0x2e, 0, 4),
+ PMIX_ENT(SOUND_MIXER_MIC, 0x0a, 0, 3, 0x00, 0, 0),
+ PMIX_ENT(SOUND_MIXER_CD, 0x28, 4, 4, 0x28, 0, 4),
PMIX_ENT(SOUND_MIXER_IMIX, 0x00, 0, 0, 0x00, 0, 0),
PMIX_ENT(SOUND_MIXER_ALTPCM, 0x00, 0, 0, 0x00, 0, 0),
PMIX_ENT(SOUND_MIXER_RECLEV, 0x00, 0, 0, 0x00, 0, 0)
@@ -280,15 +280,15 @@ mixer_tab sbpro_mix = {
#ifdef __SGNXPRO__
mixer_tab sgnxpro_mix = {
- PMIX_ENT(SOUND_MIXER_VOLUME, 0x22, 7, 4, 0x22, 3, 4),
- PMIX_ENT(SOUND_MIXER_BASS, 0x46, 2, 3, 0x00, 0, 0),
- PMIX_ENT(SOUND_MIXER_TREBLE, 0x44, 2, 3, 0x00, 0, 0),
- PMIX_ENT(SOUND_MIXER_SYNTH, 0x26, 7, 4, 0x26, 3, 4),
- PMIX_ENT(SOUND_MIXER_PCM, 0x04, 7, 4, 0x04, 3, 4),
- PMIX_ENT(SOUND_MIXER_SPEAKER, 0x42, 2, 3, 0x00, 0, 0),
- PMIX_ENT(SOUND_MIXER_LINE, 0x2e, 7, 4, 0x2e, 3, 4),
- PMIX_ENT(SOUND_MIXER_MIC, 0x0a, 2, 3, 0x00, 0, 0),
- PMIX_ENT(SOUND_MIXER_CD, 0x28, 7, 4, 0x28, 3, 4),
+ PMIX_ENT(SOUND_MIXER_VOLUME, 0x22, 4, 4, 0x22, 0, 4),
+ PMIX_ENT(SOUND_MIXER_BASS, 0x46, 0, 3, 0x00, 0, 0),
+ PMIX_ENT(SOUND_MIXER_TREBLE, 0x44, 0, 3, 0x00, 0, 0),
+ PMIX_ENT(SOUND_MIXER_SYNTH, 0x26, 4, 4, 0x26, 0, 4),
+ PMIX_ENT(SOUND_MIXER_PCM, 0x04, 4, 4, 0x04, 0, 4),
+ PMIX_ENT(SOUND_MIXER_SPEAKER, 0x42, 0, 3, 0x00, 0, 0),
+ PMIX_ENT(SOUND_MIXER_LINE, 0x2e, 4, 4, 0x2e, 0, 4),
+ PMIX_ENT(SOUND_MIXER_MIC, 0x0a, 0, 3, 0x00, 0, 0),
+ PMIX_ENT(SOUND_MIXER_CD, 0x28, 4, 4, 0x28, 0, 4),
PMIX_ENT(SOUND_MIXER_IMIX, 0x00, 0, 0, 0x00, 0, 0),
PMIX_ENT(SOUND_MIXER_ALTPCM, 0x00, 0, 0, 0x00, 0, 0),
PMIX_ENT(SOUND_MIXER_RECLEV, 0x00, 0, 0, 0x00, 0, 0),
diff --git a/sys/dev/sound/isa/sb16.c b/sys/dev/sound/isa/sb16.c
index 06599ec7d010a..4bd5825664398 100644
--- a/sys/dev/sound/isa/sb16.c
+++ b/sys/dev/sound/isa/sb16.c
@@ -337,7 +337,7 @@ again:
/*
* the sb16 might have multiple sources etc.
*/
- if (d->bd_flags & BD_F_SB16 && (c & 3) )
+ if ((d->bd_flags & BD_F_SB16) && (c & 3))
goto again;
}
@@ -428,29 +428,63 @@ sb_callback(snddev_info *d, int reason)
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
- };
- }
+ }
+ else if (d->bd_flags & BD_F_ESS) {
+ u_char c;
+
+ DEB(printf("SND_CB_INIT, play_fmt == 0x%x, rec_fmt == 0x%x\n",
+ (int) d->play_fmt, (int) d->rec_fmt));
+
+ /* autoinit DMA mode */
+ if (d->play_fmt)
+ ess_write(d->io_base, 0xb8, 0x04);
+ else
+ ess_write(d->io_base, 0xb8, 0x0e);
+
+ c = (ess_read(d->io_base, 0xa8) & ~0x03) | 0x01;
+ if ((d->flags & SND_F_STEREO) == 0)
+ c++;
+ ess_write(d->io_base, 0xa8, c); /* select mono/stereo */
+ ess_write(d->io_base, 0xb9, 2); /* demand 4 bytes/transfer */
+
+ switch (d->play_fmt ? d->play_fmt : d->rec_fmt) {
+ case AFMT_S16_LE:
+ if (d->flags & SND_F_STEREO) {
+ /* 16 bit stereo */
+ if (d->play_fmt)
+ ess_write(d->io_base, 0xb6, 0x00);
+ ess_write(d->io_base, 0xb7, 0x71);
+ ess_write(d->io_base, 0xb7, 0xbc);
+ }
+ else {
+ /* 16 bit mono */
+ if (d->play_fmt)
+ ess_write(d->io_base, 0xb6, 0x00);
+ ess_write(d->io_base, 0xb7, 0x71);
+ ess_write(d->io_base, 0xb7, 0xf4);
+ }
+ break;
+ case AFMT_U8:
+ if (d->flags & SND_F_STEREO) {
+ /* 8 bit stereo */
+ if (d->play_fmt)
+ ess_write(d->io_base, 0xb6, 0x80);
+ ess_write(d->io_base, 0xb7, 0x51);
+ ess_write(d->io_base, 0xb7, 0x98);
+ }
+ else {
+ /* 8 bit mono */
+ if (d->play_fmt)
+ ess_write(d->io_base, 0xb6, 0x80);
+ ess_write(d->io_base, 0xb7, 0x51);
+ ess_write(d->io_base, 0xb7, 0xd0);
+ }
+ break;
+ }
+ ess_write(d->io_base, 0xb1,
+ ess_read(d->io_base, 0xb1) | 0x50);
+ ess_write(d->io_base, 0xb2,
+ ess_read(d->io_base, 0xb1) | 0x50);
}
reset_dbuf(& (d->dbuf_in), SND_CHAN_RD );
reset_dbuf(& (d->dbuf_out), SND_CHAN_WR );
@@ -512,10 +546,18 @@ sb_callback(snddev_info *d, int reason)
sb_cmd(d->io_base, c );
sb_cmd3(d->io_base, c1 , l - 1) ;
} else if (d->bd_flags & BD_F_ESS) {
- /* XXX this code is still incomplete */
- sb_cmd2(d->io_base, 0xb8, rd ? 4 : 0xe ) ; /* auto dma */
- sb_cmd2(d->io_base, 0xa8, d->flags & SND_F_STEREO ? 1 : 2) ;
- sb_cmd2(d->io_base, 0xb9, 2) ; /* demand dma */
+ u_long fmt = rd ? d->rec_fmt : d->play_fmt;
+
+ DEB(printf("SND_CB_START: %s (%d)\n", rd ? "rd" : "wr", l));
+ if (fmt == AFMT_S16_LE)
+ l >>= 1;
+ l--;
+ if (!rd)
+ sb_cmd(d->io_base, DSP_CMD_SPKON);
+ ess_write(d->io_base, 0xa4, l);
+ ess_write(d->io_base, 0xa5, l >> 8);
+ ess_write(d->io_base, 0xb8,
+ ess_read(d->io_base, 0xb8) | (rd ? 0x0f : 0x05));
} else { /* SBPro -- stereo not supported */
u_char c ;
if (!rd)
@@ -546,6 +588,7 @@ sb_callback(snddev_info *d, int reason)
case SND_CB_STOP :
{
int cmd = DSP_CMD_DMAPAUSE_8 ; /* default: halt 8 bit chan */
+ DEB(printf("SND_CB_XXX: reason 0x%x\n", reason));
if ( b->chan > 4
|| (rd && d->rec_fmt == AFMT_S16_LE)
|| (!rd && d->play_fmt == AFMT_S16_LE)
@@ -722,14 +765,22 @@ sb_dsp_init(snddev_info *d, struct isa_device *dev)
/* the ESS488 can be treated as an SBPRO */
printf("ESS488 (rev %d)\n", ess_minor & 0x0f);
break ;
- } else if (ess_major == 0x68 && (ess_minor & 0xf0) == 0x80) {
- int rev = ess_minor & 0xf ;
- if ( rev >= 8 )
- printf("ESS1868 (rev %d)\n", rev);
- else
- printf("ESS688 (rev %d)\n", rev);
- /* d->audio_fmt |= AFMT_S16_LE; */ /* not yet... */
- break ; /* XXX */
+ }
+ else if (ess_major == 0x68 && (ess_minor & 0xf0) == 0x80) {
+ u_char cfg;
+ u_char bits;
+ int rev = ess_minor & 0xf;
+
+ if (rev >= 8)
+ printf("ESS1868 (rev %d)\n", rev);
+ else
+ printf("ESS688 (rev %d)\n", rev);
+ d->bd_flags |= BD_F_ESS;
+ d->audio_fmt |= AFMT_S16_LE;
+
+ /* enable extended ESS mode */
+ sb_cmd(d->io_base, 0xc6);
+ break;
} else {
printf("Unknown card 0x%x 0x%x -- hope it is SBPRO\n",
ess_major, ess_minor);
@@ -831,9 +882,9 @@ sb_setmixer(int io_base, u_int port, u_int value)
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);
- outb(io_base + 5, (u_char) (value & 0xff));
+ outb(io_base + SB_MIX_DATA, (u_char) (value & 0xff));
DELAY(10);
splx(flags);
}
@@ -1210,10 +1261,12 @@ ess1868_attach(u_long csn, u_long vend_id, char *name,
dev->id_drq = d.drq[0] ; /* primary dma */
dev->id_irq = (1 << d.irq[0] ) ;
- dev->id_intr = pcmintr ;
+ dev->id_intr = (inthand2_t *)pcmintr ;
dev->id_flags = 0 /* DV_F_DUAL_DMA | (d.drq[1] ) */;
+#if 0
snddev_last_probed->probe(dev); /* not really necessary but doesn't harm */
+#endif
pcmattach(dev);
}
@@ -1291,7 +1344,7 @@ sb16pnp_attach(u_long csn, u_long vend_id, char *name,
dev->id_drq = d.drq[0] ; /* primary dma */
dev->id_irq = (1 << d.irq[0] ) ;
- dev->id_intr = pcmintr ;
+ dev->id_intr = (inthand2_t *)pcmintr ;
dev->id_flags = DV_F_DUAL_DMA | (d.drq[1] ) ;
pcm_info[dev->id_unit] = tmp_d; /* pcm_info[] will be reinitialized after */
diff --git a/sys/dev/sound/isa/sb8.c b/sys/dev/sound/isa/sb8.c
index 06599ec7d010a..4bd5825664398 100644
--- a/sys/dev/sound/isa/sb8.c
+++ b/sys/dev/sound/isa/sb8.c
@@ -337,7 +337,7 @@ again:
/*
* the sb16 might have multiple sources etc.
*/
- if (d->bd_flags & BD_F_SB16 && (c & 3) )
+ if ((d->bd_flags & BD_F_SB16) && (c & 3))
goto again;
}
@@ -428,29 +428,63 @@ sb_callback(snddev_info *d, int reason)
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
- };
- }
+ }
+ else if (d->bd_flags & BD_F_ESS) {
+ u_char c;
+
+ DEB(printf("SND_CB_INIT, play_fmt == 0x%x, rec_fmt == 0x%x\n",
+ (int) d->play_fmt, (int) d->rec_fmt));
+
+ /* autoinit DMA mode */
+ if (d->play_fmt)
+ ess_write(d->io_base, 0xb8, 0x04);
+ else
+ ess_write(d->io_base, 0xb8, 0x0e);
+
+ c = (ess_read(d->io_base, 0xa8) & ~0x03) | 0x01;
+ if ((d->flags & SND_F_STEREO) == 0)
+ c++;
+ ess_write(d->io_base, 0xa8, c); /* select mono/stereo */
+ ess_write(d->io_base, 0xb9, 2); /* demand 4 bytes/transfer */
+
+ switch (d->play_fmt ? d->play_fmt : d->rec_fmt) {
+ case AFMT_S16_LE:
+ if (d->flags & SND_F_STEREO) {
+ /* 16 bit stereo */
+ if (d->play_fmt)
+ ess_write(d->io_base, 0xb6, 0x00);
+ ess_write(d->io_base, 0xb7, 0x71);
+ ess_write(d->io_base, 0xb7, 0xbc);
+ }
+ else {
+ /* 16 bit mono */
+ if (d->play_fmt)
+ ess_write(d->io_base, 0xb6, 0x00);
+ ess_write(d->io_base, 0xb7, 0x71);
+ ess_write(d->io_base, 0xb7, 0xf4);
+ }
+ break;
+ case AFMT_U8:
+ if (d->flags & SND_F_STEREO) {
+ /* 8 bit stereo */
+ if (d->play_fmt)
+ ess_write(d->io_base, 0xb6, 0x80);
+ ess_write(d->io_base, 0xb7, 0x51);
+ ess_write(d->io_base, 0xb7, 0x98);
+ }
+ else {
+ /* 8 bit mono */
+ if (d->play_fmt)
+ ess_write(d->io_base, 0xb6, 0x80);
+ ess_write(d->io_base, 0xb7, 0x51);
+ ess_write(d->io_base, 0xb7, 0xd0);
+ }
+ break;
+ }
+ ess_write(d->io_base, 0xb1,
+ ess_read(d->io_base, 0xb1) | 0x50);
+ ess_write(d->io_base, 0xb2,
+ ess_read(d->io_base, 0xb1) | 0x50);
}
reset_dbuf(& (d->dbuf_in), SND_CHAN_RD );
reset_dbuf(& (d->dbuf_out), SND_CHAN_WR );
@@ -512,10 +546,18 @@ sb_callback(snddev_info *d, int reason)
sb_cmd(d->io_base, c );
sb_cmd3(d->io_base, c1 , l - 1) ;
} else if (d->bd_flags & BD_F_ESS) {
- /* XXX this code is still incomplete */
- sb_cmd2(d->io_base, 0xb8, rd ? 4 : 0xe ) ; /* auto dma */
- sb_cmd2(d->io_base, 0xa8, d->flags & SND_F_STEREO ? 1 : 2) ;
- sb_cmd2(d->io_base, 0xb9, 2) ; /* demand dma */
+ u_long fmt = rd ? d->rec_fmt : d->play_fmt;
+
+ DEB(printf("SND_CB_START: %s (%d)\n", rd ? "rd" : "wr", l));
+ if (fmt == AFMT_S16_LE)
+ l >>= 1;
+ l--;
+ if (!rd)
+ sb_cmd(d->io_base, DSP_CMD_SPKON);
+ ess_write(d->io_base, 0xa4, l);
+ ess_write(d->io_base, 0xa5, l >> 8);
+ ess_write(d->io_base, 0xb8,
+ ess_read(d->io_base, 0xb8) | (rd ? 0x0f : 0x05));
} else { /* SBPro -- stereo not supported */
u_char c ;
if (!rd)
@@ -546,6 +588,7 @@ sb_callback(snddev_info *d, int reason)
case SND_CB_STOP :
{
int cmd = DSP_CMD_DMAPAUSE_8 ; /* default: halt 8 bit chan */
+ DEB(printf("SND_CB_XXX: reason 0x%x\n", reason));
if ( b->chan > 4
|| (rd && d->rec_fmt == AFMT_S16_LE)
|| (!rd && d->play_fmt == AFMT_S16_LE)
@@ -722,14 +765,22 @@ sb_dsp_init(snddev_info *d, struct isa_device *dev)
/* the ESS488 can be treated as an SBPRO */
printf("ESS488 (rev %d)\n", ess_minor & 0x0f);
break ;
- } else if (ess_major == 0x68 && (ess_minor & 0xf0) == 0x80) {
- int rev = ess_minor & 0xf ;
- if ( rev >= 8 )
- printf("ESS1868 (rev %d)\n", rev);
- else
- printf("ESS688 (rev %d)\n", rev);
- /* d->audio_fmt |= AFMT_S16_LE; */ /* not yet... */
- break ; /* XXX */
+ }
+ else if (ess_major == 0x68 && (ess_minor & 0xf0) == 0x80) {
+ u_char cfg;
+ u_char bits;
+ int rev = ess_minor & 0xf;
+
+ if (rev >= 8)
+ printf("ESS1868 (rev %d)\n", rev);
+ else
+ printf("ESS688 (rev %d)\n", rev);
+ d->bd_flags |= BD_F_ESS;
+ d->audio_fmt |= AFMT_S16_LE;
+
+ /* enable extended ESS mode */
+ sb_cmd(d->io_base, 0xc6);
+ break;
} else {
printf("Unknown card 0x%x 0x%x -- hope it is SBPRO\n",
ess_major, ess_minor);
@@ -831,9 +882,9 @@ sb_setmixer(int io_base, u_int port, u_int value)
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);
- outb(io_base + 5, (u_char) (value & 0xff));
+ outb(io_base + SB_MIX_DATA, (u_char) (value & 0xff));
DELAY(10);
splx(flags);
}
@@ -1210,10 +1261,12 @@ ess1868_attach(u_long csn, u_long vend_id, char *name,
dev->id_drq = d.drq[0] ; /* primary dma */
dev->id_irq = (1 << d.irq[0] ) ;
- dev->id_intr = pcmintr ;
+ dev->id_intr = (inthand2_t *)pcmintr ;
dev->id_flags = 0 /* DV_F_DUAL_DMA | (d.drq[1] ) */;
+#if 0
snddev_last_probed->probe(dev); /* not really necessary but doesn't harm */
+#endif
pcmattach(dev);
}
@@ -1291,7 +1344,7 @@ sb16pnp_attach(u_long csn, u_long vend_id, char *name,
dev->id_drq = d.drq[0] ; /* primary dma */
dev->id_irq = (1 << d.irq[0] ) ;
- dev->id_intr = pcmintr ;
+ dev->id_intr = (inthand2_t *)pcmintr ;
dev->id_flags = DV_F_DUAL_DMA | (d.drq[1] ) ;
pcm_info[dev->id_unit] = tmp_d; /* pcm_info[] will be reinitialized after */