summaryrefslogtreecommitdiffstats
path: root/sys/dev/sound
diff options
context:
space:
mode:
authorcg <cg@FreeBSD.org>1999-12-12 02:30:19 +0000
committercg <cg@FreeBSD.org>1999-12-12 02:30:19 +0000
commit99bed6d33e4b265f59b3246349fd4bc5b9d7f290 (patch)
tree2de4c3742d0aa34feb9901bda05065133d6ded33 /sys/dev/sound
parent7c2cd0059f46396427902ef62f11257e86fee985 (diff)
downloadFreeBSD-src-99bed6d33e4b265f59b3246349fd4bc5b9d7f290.zip
FreeBSD-src-99bed6d33e4b265f59b3246349fd4bc5b9d7f290.tar.gz
make sb dependant on sbc
add support for non-pnp cards to sbc move card identification to sbc channel-swapping code is in sb now instead of dsp vibra16x support is still broken, but will be fixed soon note: sbc is now compulsory for sb cards for pnp cards use: device sbc0 for non-pnp cards eg: device sbc0 at isa? port 0x240 irq 5 drq 3 flags 0x15 (hints as oldpcm) both in addition to: device pcm0 Reviewed by: tanimura,dfr Said he liked it: peter
Diffstat (limited to 'sys/dev/sound')
-rw-r--r--sys/dev/sound/isa/sb.c449
-rw-r--r--sys/dev/sound/isa/sb.h94
-rw-r--r--sys/dev/sound/isa/sb16.c449
-rw-r--r--sys/dev/sound/isa/sb8.c449
-rw-r--r--sys/dev/sound/isa/sbc.c411
5 files changed, 636 insertions, 1216 deletions
diff --git a/sys/dev/sound/isa/sb.c b/sys/dev/sound/isa/sb.c
index 6aba674..ef55248 100644
--- a/sys/dev/sound/isa/sb.c
+++ b/sys/dev/sound/isa/sb.c
@@ -60,6 +60,7 @@ static int esschan_setblocksize(void *data, u_int32_t blocksize);
static int esschan_trigger(void *data, int go);
static int esschan_getptr(void *data);
static pcmchan_caps *esschan_getcaps(void *data);
+
static pcmchan_caps sb_playcaps = {
4000, 22050,
AFMT_U8,
@@ -84,18 +85,24 @@ static pcmchan_caps sbpro_reccaps = {
AFMT_STEREO | AFMT_U8
};
-static pcmchan_caps sb16_playcaps = {
+static pcmchan_caps sb16_hcaps = {
5000, 45000,
AFMT_STEREO | AFMT_S16_LE,
AFMT_STEREO | AFMT_S16_LE
};
-static pcmchan_caps sb16_reccaps = {
+static pcmchan_caps sb16_lcaps = {
5000, 45000,
AFMT_STEREO | AFMT_U8,
AFMT_STEREO | AFMT_U8
};
+static pcmchan_caps sb16x_caps = {
+ 5000, 49000,
+ AFMT_STEREO | AFMT_U8 /* | AFMT_S16_LE */,
+ AFMT_STEREO | AFMT_U8 /* AFMT_S16_LE */
+};
+
static pcmchan_caps ess_playcaps = {
5000, 49000,
AFMT_STEREO | AFMT_U8 | AFMT_S16_LE,
@@ -144,16 +151,11 @@ struct sb_chinfo {
struct sb_info {
struct resource *io_base; /* I/O address for the board */
- int io_rid;
struct resource *irq;
- int irq_rid;
- struct resource *drq1; /* play */
- int drq1_rid;
- struct resource *drq2; /* rec */
- int drq2_rid;
+ struct resource *drq1;
+ struct resource *drq2;
bus_dma_tag_t parent_dmat;
- int dma16, dma8;
int bd_id;
u_long bd_flags; /* board-specific flags */
struct sb_chinfo pch, rch;
@@ -166,31 +168,25 @@ static int sb_cmd(struct sb_info *sb, u_char val);
static int sb_cmd1(struct sb_info *sb, u_char cmd, int val);
static int sb_cmd2(struct sb_info *sb, u_char cmd, int val);
static u_int sb_get_byte(struct sb_info *sb);
-static int ess_write(struct sb_info *sb, u_char reg, int val);
-static int ess_read(struct sb_info *sb, u_char reg);
-
-/*
- * in the SB, there is a set of indirect "mixer" registers with
- * address at offset 4, data at offset 5
- */
static void sb_setmixer(struct sb_info *sb, u_int port, u_int value);
static int sb_getmixer(struct sb_info *sb, u_int port);
-
-static void sb_intr(void *arg);
-static void ess_intr(void *arg);
-static int sb_init(device_t dev, struct sb_info *sb);
static int sb_reset_dsp(struct sb_info *sb);
+static void sb_intr(void *arg);
static int sb_format(struct sb_chinfo *ch, u_int32_t format);
static int sb_speed(struct sb_chinfo *ch, int speed);
static int sb_start(struct sb_chinfo *ch);
static int sb_stop(struct sb_chinfo *ch);
+static int ess_write(struct sb_info *sb, u_char reg, int val);
+static int ess_read(struct sb_info *sb, u_char reg);
+static void ess_intr(void *arg);
static int ess_format(struct sb_chinfo *ch, u_int32_t format);
static int ess_speed(struct sb_chinfo *ch, int speed);
static int ess_start(struct sb_chinfo *ch);
static int ess_stop(struct sb_chinfo *ch);
static int ess_abort(struct sb_chinfo *ch);
+
static int sbmix_init(snd_mixer *m);
static int sbmix_set(snd_mixer *m, unsigned dev, unsigned left, unsigned right);
static int sbmix_setrecsrc(snd_mixer *m, u_int32_t src);
@@ -377,20 +373,19 @@ sb_release_resources(struct sb_info *sb, device_t dev)
{
/* should we bus_teardown_intr here? */
if (sb->irq) {
- bus_release_resource(dev, SYS_RES_IRQ, sb->irq_rid, sb->irq);
+ bus_release_resource(dev, SYS_RES_IRQ, 0, sb->irq);
sb->irq = 0;
}
if (sb->drq1) {
- bus_release_resource(dev, SYS_RES_DRQ, sb->drq1_rid, sb->drq1);
+ bus_release_resource(dev, SYS_RES_DRQ, 0, sb->drq1);
sb->drq1 = 0;
}
if (sb->drq2) {
- bus_release_resource(dev, SYS_RES_DRQ, sb->drq2_rid, sb->drq2);
+ bus_release_resource(dev, SYS_RES_DRQ, 1, sb->drq2);
sb->drq2 = 0;
}
if (sb->io_base) {
- bus_release_resource(dev, SYS_RES_IOPORT, sb->io_rid,
- sb->io_base);
+ bus_release_resource(dev, SYS_RES_IOPORT, 0, sb->io_base);
sb->io_base = 0;
}
free(sb, M_DEVBUF);
@@ -399,184 +394,66 @@ sb_release_resources(struct sb_info *sb, device_t dev)
static int
sb_alloc_resources(struct sb_info *sb, device_t dev)
{
+ int rid;
+
+ rid = 0;
if (!sb->io_base)
sb->io_base = bus_alloc_resource(dev, SYS_RES_IOPORT,
- &sb->io_rid, 0, ~0, 1,
+ &rid, 0, ~0, 1,
RF_ACTIVE);
+ rid = 0;
if (!sb->irq)
sb->irq = bus_alloc_resource(dev, SYS_RES_IRQ,
- &sb->irq_rid, 0, ~0, 1,
+ &rid, 0, ~0, 1,
RF_ACTIVE);
+ rid = 0;
if (!sb->drq1)
sb->drq1 = bus_alloc_resource(dev, SYS_RES_DRQ,
- &sb->drq1_rid, 0, ~0, 1,
+ &rid, 0, ~0, 1,
RF_ACTIVE);
- if (!sb->drq2 && sb->drq2_rid > 0)
+ rid = 1;
+ if (!sb->drq2)
sb->drq2 = bus_alloc_resource(dev, SYS_RES_DRQ,
- &sb->drq2_rid, 0, ~0, 1,
+ &rid, 0, ~0, 1,
RF_ACTIVE);
if (sb->io_base && sb->drq1 && sb->irq) {
- sb->dma8 = rman_get_start(sb->drq1);
- isa_dma_acquire(sb->dma8);
- isa_dmainit(sb->dma8, DSP_BUFFSIZE);
+ isa_dma_acquire(rman_get_start(sb->drq1));
+ isa_dmainit(rman_get_start(sb->drq1), DSP_BUFFSIZE);
if (sb->drq2) {
- sb->dma16 = rman_get_start(sb->drq2);
- isa_dma_acquire(sb->dma16);
- isa_dmainit(sb->dma16, DSP_BUFFSIZE);
- } else sb->dma16 = sb->dma8;
-
- if (sb->dma8 > sb->dma16) {
- int tmp = sb->dma16;
- sb->dma16 = sb->dma8;
- sb->dma8 = tmp;
+ isa_dma_acquire(rman_get_start(sb->drq2));
+ isa_dmainit(rman_get_start(sb->drq2), DSP_BUFFSIZE);
}
+
return 0;
} else return ENXIO;
}
-static int
-sb_identify_board(device_t dev, struct sb_info *sb)
-{
- char *fmt = NULL;
- static char buf[64];
- int essver = 0;
-
- sb_cmd(sb, DSP_CMD_GETVER); /* Get version */
- sb->bd_id = (sb_get_byte(sb) << 8) | sb_get_byte(sb);
-
- switch (sb->bd_id >> 8) {
- case 1: /* old sound blaster has nothing... */
- case 2:
- fmt = "SoundBlaster %d.%d" ; /* default */
- break;
-
- case 3:
- fmt = "SoundBlaster Pro %d.%d";
- if (sb->bd_id == 0x301) {
- int rev;
-
- /* Try to detect ESS chips. */
- sb_cmd(sb, DSP_CMD_GETID); /* Return ident. bytes. */
- essver = (sb_get_byte(sb) << 8) | sb_get_byte(sb);
- rev = essver & 0x000f;
- essver &= 0xfff0;
- if (essver == 0x4880) {
- /* the ESS488 can be treated as an SBPRO */
- fmt = "SoundBlaster Pro (ESS488 rev %d)";
- } else if (essver == 0x6880) {
- if (rev < 8) fmt = "ESS688 rev %d";
- else fmt = "ESS1868 rev %d";
- sb->bd_flags |= BD_F_ESS;
- } else return ENXIO;
- sb->bd_id &= 0xff00;
- sb->bd_id |= ((essver & 0xf000) >> 8) | rev;
- }
- break;
-
- case 4:
- sb->bd_flags |= BD_F_SB16;
- if (sb->bd_flags & BD_F_SB16X) fmt = "SB16 ViBRA16X %d.%d";
- else fmt = "SoundBlaster 16 %d.%d";
- break;
-
- default:
- device_printf(dev, "failed to get SB version (%x)\n",
- sb->bd_id);
- return ENXIO;
- }
- if (essver) snprintf(buf, sizeof buf, fmt, sb->bd_id & 0x000f);
- else snprintf(buf, sizeof buf, fmt, sb->bd_id >> 8, sb->bd_id & 0xff);
- device_set_desc_copy(dev, buf);
- return sb_reset_dsp(sb);
-}
-
-static int
-sb_init(device_t dev, struct sb_info *sb)
-{
- int x, irq;
-
- sb->bd_flags &= ~BD_F_MIX_MASK;
- /* do various initializations depending on board id. */
- switch (sb->bd_id >> 8) {
- case 1: /* old sound blaster has nothing... */
- break;
-
- case 2:
- sb->bd_flags |= BD_F_DUP_MIDI;
- if (sb->bd_id > 0x200) sb->bd_flags |= BD_F_MIX_CT1335;
- break;
-
- case 3:
- sb->bd_flags |= BD_F_DUP_MIDI | BD_F_MIX_CT1345;
- break;
-
- case 4:
- sb->bd_flags |= BD_F_SB16 | BD_F_MIX_CT1745;
- if (sb->dma16 != sb->dma8) sb->bd_flags |= BD_F_DUPLEX;
-
- /* soft irq/dma configuration */
- x = -1;
- irq = rman_get_start(sb->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(sb, IRQ_NR, x);
- sb_setmixer(sb, DMA_NR, (1 << sb->dma16) | (1 << sb->dma8));
- break;
- }
- return 0;
-}
-
-static int
-sb_probe(device_t dev)
+static void
+sb16_swap(void *v, int dir)
{
- snddev_info *d = device_get_softc(dev);
- struct sb_info *sb;
- int allocated, i;
- int error;
-
- if (isa_get_vendorid(dev)) return ENXIO; /* not yet */
-
- device_set_desc(dev, "SoundBlaster");
- bzero(d, sizeof *d);
- sb = (struct sb_info *)malloc(sizeof *sb, M_DEVBUF, M_NOWAIT);
- if (!sb) return ENXIO;
- bzero(sb, sizeof *sb);
-
- allocated = 0;
- sb->io_rid = 0;
- sb->io_base = bus_alloc_resource(dev, SYS_RES_IOPORT, &sb->io_rid,
- 0, ~0, 16, RF_ACTIVE);
- if (!sb->io_base) {
- BVDDB(printf("sb_probe: no addr, trying (0x220, 0x240)\n"));
- allocated = 1;
- sb->io_rid = 0;
- sb->io_base = bus_alloc_resource(dev, SYS_RES_IOPORT,
- &sb->io_rid, 0x220, 0x22f,
- 16, RF_ACTIVE);
- if (!sb->io_base) {
- sb->io_base = bus_alloc_resource(dev, SYS_RES_IOPORT,
- &sb->io_rid, 0x240,
- 0x24f, 16, RF_ACTIVE);
+ struct sb_info *sb = v;
+ int pb = sb->pch.buffer->dl;
+ int rb = sb->rch.buffer->dl;
+ int pc = sb->pch.buffer->chan;
+ int rc = sb->rch.buffer->chan;
+ int swp = 0;
+
+ if (!pb && !rb) {
+ if (dir == PCMDIR_PLAY && pc < 4) swp = 1;
+ else if (dir == PCMDIR_REC && rc < 4) swp = 1;
+ if (sb->bd_flags & BD_F_SB16X) swp = !swp;
+ if (swp) {
+ int t;
+
+ t = sb->pch.buffer->chan;
+ sb->pch.buffer->chan = sb->rch.buffer->chan;
+ sb->rch.buffer->chan = t;
+ sb->pch.buffer->dir = B_WRITE;
+ sb->rch.buffer->dir = B_READ;
}
- }
- if (!sb->io_base) return ENXIO;
-
- error = sb_reset_dsp(sb);
- if (error) goto no;
- error = sb_identify_board(dev, sb);
- if (error) goto no;
-no:
- i = sb->io_rid;
- sb_release_resources(sb, dev);
- if (allocated) bus_delete_resource(dev, SYS_RES_IOPORT, i);
- return error;
+ }
}
static int
@@ -584,29 +461,21 @@ sb_doattach(device_t dev, struct sb_info *sb)
{
snddev_info *d = device_get_softc(dev);
void *ih;
- int error;
char status[SND_STATUSLEN];
- sb->irq_rid = 0;
- sb->drq1_rid = 0;
- sb->drq2_rid = 1;
if (sb_alloc_resources(sb, dev)) goto no;
- error = sb_reset_dsp(sb);
- if (error) goto no;
- error = sb_identify_board(dev, sb);
- if (error) goto no;
-
- sb_init(dev, sb);
+ if (sb_reset_dsp(sb)) goto no;
mixer_init(d, &sb_mixer, sb);
+
if (sb->bd_flags & BD_F_ESS)
bus_setup_intr(dev, sb->irq, INTR_TYPE_TTY, ess_intr, sb, &ih);
else
bus_setup_intr(dev, sb->irq, INTR_TYPE_TTY, sb_intr, sb, &ih);
-
- if (sb->bd_flags & BD_F_SB16)
- pcm_setflags(dev, pcm_getflags(dev) | SD_F_EVILSB16);
- if (sb->dma16 == sb->dma8)
+ if ((sb->bd_flags & BD_F_SB16) && !(sb->bd_flags & BD_F_SB16X))
+ pcm_setswap(dev, sb16_swap);
+ if (!sb->drq2)
pcm_setflags(dev, pcm_getflags(dev) | SD_F_SIMPLEX);
+
if (bus_dma_tag_create(/*parent*/NULL, /*alignment*/2, /*boundary*/0,
/*lowaddr*/BUS_SPACE_MAXADDR_24BIT,
/*highaddr*/BUS_SPACE_MAXADDR,
@@ -618,11 +487,11 @@ sb_doattach(device_t dev, struct sb_info *sb)
goto no;
}
- snprintf(status, SND_STATUSLEN, "at io 0x%lx irq %ld drq %d",
+ snprintf(status, SND_STATUSLEN, "at io 0x%lx irq %ld drq %ld",
rman_get_start(sb->io_base), rman_get_start(sb->irq),
- sb->dma8);
- if (sb->dma16 != sb->dma8) snprintf(status + strlen(status),
- SND_STATUSLEN - strlen(status), ":%d", sb->dma16);
+ rman_get_start(sb->drq1));
+ if (sb->drq2) snprintf(status + strlen(status), SND_STATUSLEN - strlen(status),
+ ":%ld", rman_get_start(sb->drq2));
if (pcm_register(dev, sb, 1, 1)) goto no;
if (sb->bd_flags & BD_F_ESS) {
@@ -641,57 +510,6 @@ no:
return ENXIO;
}
-static int
-sb_attach(device_t dev)
-{
- struct sb_info *sb;
- int flags = device_get_flags(dev);
-
- if (flags & DV_F_DUAL_DMA) {
- bus_set_resource(dev, SYS_RES_DRQ, 1,
- flags & DV_F_DRQ_MASK, 1);
- }
- sb = (struct sb_info *)malloc(sizeof *sb, M_DEVBUF, M_NOWAIT);
- if (!sb) return ENXIO;
- bzero(sb, sizeof *sb);
-
- /* XXX in probe should set io resource to right val instead of this */
- sb->io_rid = 0;
- sb->io_base = bus_alloc_resource(dev, SYS_RES_IOPORT, &sb->io_rid,
- 0, ~0, 16, RF_ACTIVE);
- if (!sb->io_base) {
- BVDDB(printf("sb_probe: no addr, trying (0x220, 0x240)\n"));
- sb->io_rid = 0;
- sb->io_base = bus_alloc_resource(dev, SYS_RES_IOPORT,
- &sb->io_rid, 0x220, 0x22f,
- 16, RF_ACTIVE);
- if (!sb->io_base) {
- sb->io_base = bus_alloc_resource(dev, SYS_RES_IOPORT,
- &sb->io_rid, 0x240,
- 0x24f, 16, RF_ACTIVE);
- }
- }
- if (!sb->io_base) return ENXIO;
-
- return sb_doattach(dev, sb);
-}
-
-static device_method_t sb_methods[] = {
- /* Device interface */
- DEVMETHOD(device_probe, sb_probe),
- DEVMETHOD(device_attach, sb_attach),
-
- { 0, 0 }
-};
-
-static driver_t sb_driver = {
- "pcm",
- sb_methods,
- sizeof(snddev_info),
-};
-
-DRIVER_MODULE(sb, isa, sb_driver, pcm_devclass, 0, 0);
-
static void
sb_intr(void *arg)
{
@@ -829,6 +647,7 @@ sb_start(struct sb_chinfo *ch)
int b16 = (ch->fmt & AFMT_S16_LE)? 1 : 0;
int stereo = (ch->fmt & AFMT_STEREO)? 1 : 0;
int l = ch->buffer->dl;
+ int dh = ch->buffer->chan > 3;
u_char i1, i2 = 0;
if (b16) l >>= 1;
@@ -837,7 +656,7 @@ sb_start(struct sb_chinfo *ch)
if (sb->bd_flags & BD_F_SB16) {
i1 = DSP_F16_AUTO | DSP_F16_FIFO_ON |
(play? DSP_F16_DAC : DSP_F16_ADC);
- i1 |= (b16 && (sb->bd_flags & BD_F_DUPLEX))? DSP_DMA16 : DSP_DMA8;
+ i1 |= (b16 || dh)? DSP_DMA16 : DSP_DMA8;
i2 = (stereo? DSP_F16_STEREO : 0) | (b16? DSP_F16_SIGNED : 0);
sb_cmd(sb, i1);
sb_cmd2(sb, i2, l);
@@ -999,7 +818,8 @@ sbchan_init(void *devinfo, snd_dbuf *b, pcm_channel *c, int dir)
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)? sb->dma16 : sb->dma8;
+ ch->buffer->chan = (dir == PCMDIR_PLAY)? rman_get_start(sb->drq2)
+ : rman_get_start(sb->drq1);
return ch;
}
@@ -1053,12 +873,14 @@ sbchan_getcaps(void *data)
{
struct sb_chinfo *ch = data;
int p = (ch->dir == PCMDIR_PLAY)? 1 : 0;
- if (ch->parent->bd_id <= 0x200)
+ if (ch->parent->bd_id < 0x300)
return p? &sb_playcaps : &sb_reccaps;
- else if (ch->parent->bd_id >= 0x400)
- return p? &sb16_playcaps : &sb16_reccaps;
- else
+ else if (ch->parent->bd_id < 0x400)
return p? &sbpro_playcaps : &sbpro_reccaps;
+ else if (ch->parent->bd_flags & BD_F_SB16X)
+ return &sb16x_caps;
+ else
+ return (ch->buffer->chan >= 4)? &sb16_hcaps : &sb16_lcaps;
}
/* channel interface for ESS18xx */
#ifdef notyet
@@ -1253,101 +1075,21 @@ sbmix_setrecsrc(snd_mixer *m, u_int32_t src)
}
static int
-sbpnp_probe(device_t dev)
-{
- char *s = NULL;
- u_int32_t logical_id = isa_get_logicalid(dev);
-
- switch(logical_id) {
- case 0x01000000: /* @@@0001 */
- s = "Avance Asound 100";
- break;
-
- case 0x01100000: /* @@@1001 */
- s = "Avance Asound 110";
- break;
-
- case 0x01200000: /* @@@2001 */
- s = "Avance Logic ALS120";
- break;
-
- case 0x68187316: /* ESS1868 */
- s = "ESS1868";
- break;
-
- case 0x69187316: /* ESS1869 */
- case 0xacb0110e: /* Compaq's Presario 1621 ESS1869 */
- s = "ESS1869";
- break;
-
- case 0x79187316: /* ESS1879 */
- s = "ESS1879";
- break;
-
- case 0x88187316: /* ESS1888 */
- s = "ESS1888";
- break;
- }
- if (s) {
- device_set_desc(dev, s);
- return (0);
- }
- return ENXIO;
-}
-
-static int
-sbpnp_attach(device_t dev)
-{
- struct sb_info *sb;
- u_int32_t vend_id = isa_get_vendorid(dev);
-
- sb = (struct sb_info *)malloc(sizeof *sb, M_DEVBUF, M_NOWAIT);
- if (!sb) return ENXIO;
- bzero(sb, sizeof *sb);
-
- switch(vend_id) {
- case 0xf0008c0e:
- case 0x10019305:
- case 0x20019305:
- /* XXX add here the vend_id for other vibra16X cards... */
- sb->bd_flags = BD_F_SB16X;
- }
- return sb_doattach(dev, sb);
-}
-
-static device_method_t sbpnp_methods[] = {
- /* Device interface */
- DEVMETHOD(device_probe, sbpnp_probe),
- DEVMETHOD(device_attach, sbpnp_attach),
-
- { 0, 0 }
-};
-
-static driver_t sbpnp_driver = {
- "pcm",
- sbpnp_methods,
- sizeof(snddev_info),
-};
-
-DRIVER_MODULE(sbpnp, isa, sbpnp_driver, pcm_devclass, 0, 0);
-
-#if NSBC > 0
-#define DESCSTR " PCM Audio"
-static int
sbsbc_probe(device_t dev)
{
- char *s = NULL;
- struct sndcard_func *func;
+ char buf[64];
+ u_int32_t func, ver, r;
/* The parent device has already been probed. */
-
- func = device_get_ivars(dev);
- if (func == NULL || func->func != SCF_PCM)
+ r = BUS_READ_IVAR(device_get_parent(dev), dev, 0, &func);
+ if (func != SCF_PCM)
return (ENXIO);
- s = "SB PCM Audio";
+ r = BUS_READ_IVAR(device_get_parent(dev), dev, 1, &ver);
+ ver &= 0x0000ffff;
+ snprintf(buf, sizeof buf, "SB DSP %d.%02d", ver >> 8, ver & 0xff);
+ device_set_desc_copy(dev, buf);
- device_set_desc(dev, s);
return 0;
}
@@ -1355,22 +1097,16 @@ static int
sbsbc_attach(device_t dev)
{
struct sb_info *sb;
- u_int32_t vend_id;
- device_t sbc;
+ u_int32_t ver;
- sbc = device_get_parent(dev);
- vend_id = isa_get_vendorid(sbc);
sb = (struct sb_info *)malloc(sizeof *sb, M_DEVBUF, M_NOWAIT);
if (!sb) return ENXIO;
bzero(sb, sizeof *sb);
- switch(vend_id) {
- case 0xf0008c0e:
- case 0x10019305:
- case 0x20019305:
- /* XXX add here the vend_id for other vibra16X cards... */
- sb->bd_flags = BD_F_SB16X;
- }
+ BUS_READ_IVAR(device_get_parent(dev), dev, 1, &ver);
+ sb->bd_id = ver & 0x0000ffff;
+ sb->bd_flags = (ver & 0xffff0000) >> 16;
+
return sb_doattach(dev, sb);
}
@@ -1390,4 +1126,5 @@ static driver_t sbsbc_driver = {
DRIVER_MODULE(sbsbc, sbc, sbsbc_driver, pcm_devclass, 0, 0);
-#endif /* NSBC > 0 */
+
+
diff --git a/sys/dev/sound/isa/sb.h b/sys/dev/sound/isa/sb.h
index 110eda0..0bb3496 100644
--- a/sys/dev/sound/isa/sb.h
+++ b/sys/dev/sound/isa/sb.h
@@ -3,11 +3,6 @@
* $FreeBSD$
*/
-typedef struct _sbdev_info {
-
-} sbdev_info ;
-
-extern int sbc_major, sbc_minor ;
/*
* sound blaster registers
*/
@@ -150,6 +145,47 @@ extern int sbc_major, sbc_minor ;
#define BD_F_DMARUN 0x2000
#define BD_F_DMARUN2 0x4000
#define BD_F_DUPLEX 0x8000
+
+/*
+ * Mixer registers of SB Pro
+ */
+#define VOC_VOL 0x04
+#define MIC_VOL 0x0A
+#define MIC_MIX 0x0A
+#define RECORD_SRC 0x0C
+#define IN_FILTER 0x0C
+#define OUT_FILTER 0x0E
+#define MASTER_VOL 0x22
+#define FM_VOL 0x26
+#define CD_VOL 0x28
+#define LINE_VOL 0x2E
+#define IRQ_NR 0x80
+#define DMA_NR 0x81
+#define IRQ_STAT 0x82
+
+/*
+ * Additional registers on the SG NX Pro
+ */
+#define COVOX_VOL 0x42
+#define TREBLE_LVL 0x44
+#define BASS_LVL 0x46
+
+#define FREQ_HI (1 << 3)/* Use High-frequency ANFI filters */
+#define FREQ_LOW 0 /* Use Low-frequency ANFI filters */
+#define FILT_ON 0 /* Yes, 0 to turn it on, 1 for off */
+#define FILT_OFF (1 << 5)
+
+#define MONO_DAC 0x00
+#define STEREO_DAC 0x02
+
+/*
+ * Mixer registers of SB16
+ */
+#define SB16_IMASK_L 0x3d
+#define SB16_IMASK_R 0x3e
+#define SB16_OMASK 0x3c
+
+#ifndef SB_NOMIXER
/*
* sound/sb_mixer.h
*
@@ -210,52 +246,6 @@ extern int sbc_major, sbc_minor ;
SOUND_MASK_IGAIN | SOUND_MASK_OGAIN | \
SOUND_MASK_VOLUME | SOUND_MASK_BASS | SOUND_MASK_TREBLE)
-/*
- * Mixer registers
- *
- * NOTE! RECORD_SRC == IN_FILTER
- */
-
-/*
- * Mixer registers of SB Pro
- */
-#define VOC_VOL 0x04
-#define MIC_VOL 0x0A
-#define MIC_MIX 0x0A
-#define RECORD_SRC 0x0C
-#define IN_FILTER 0x0C
-#define OUT_FILTER 0x0E
-#define MASTER_VOL 0x22
-#define FM_VOL 0x26
-#define CD_VOL 0x28
-#define LINE_VOL 0x2E
-#define IRQ_NR 0x80
-#define DMA_NR 0x81
-#define IRQ_STAT 0x82
-
-/*
- * Additional registers on the SG NX Pro
- */
-#define COVOX_VOL 0x42
-#define TREBLE_LVL 0x44
-#define BASS_LVL 0x46
-
-#define FREQ_HI (1 << 3)/* Use High-frequency ANFI filters */
-#define FREQ_LOW 0 /* Use Low-frequency ANFI filters */
-#define FILT_ON 0 /* Yes, 0 to turn it on, 1 for off */
-#define FILT_OFF (1 << 5)
-
-#define MONO_DAC 0x00
-#define STEREO_DAC 0x02
-
-/*
- * Mixer registers of SB16
- */
-#define SB16_IMASK_L 0x3d
-#define SB16_IMASK_R 0x3e
-#define SB16_OMASK 0x3c
-
-
#ifndef __SB_MIXER_C__
mixer_tab sbpro_mix;
mixer_tab ess_mix;
@@ -379,4 +369,4 @@ static u_char sb16_recmasks_R[SOUND_MIXER_NRDEVICES] =
#define SRC_CD 3 /* Select CD recording source */
#define SRC_LINE 7 /* Use Line-in for recording source */
-
+#endif
diff --git a/sys/dev/sound/isa/sb16.c b/sys/dev/sound/isa/sb16.c
index 6aba674..ef55248 100644
--- a/sys/dev/sound/isa/sb16.c
+++ b/sys/dev/sound/isa/sb16.c
@@ -60,6 +60,7 @@ static int esschan_setblocksize(void *data, u_int32_t blocksize);
static int esschan_trigger(void *data, int go);
static int esschan_getptr(void *data);
static pcmchan_caps *esschan_getcaps(void *data);
+
static pcmchan_caps sb_playcaps = {
4000, 22050,
AFMT_U8,
@@ -84,18 +85,24 @@ static pcmchan_caps sbpro_reccaps = {
AFMT_STEREO | AFMT_U8
};
-static pcmchan_caps sb16_playcaps = {
+static pcmchan_caps sb16_hcaps = {
5000, 45000,
AFMT_STEREO | AFMT_S16_LE,
AFMT_STEREO | AFMT_S16_LE
};
-static pcmchan_caps sb16_reccaps = {
+static pcmchan_caps sb16_lcaps = {
5000, 45000,
AFMT_STEREO | AFMT_U8,
AFMT_STEREO | AFMT_U8
};
+static pcmchan_caps sb16x_caps = {
+ 5000, 49000,
+ AFMT_STEREO | AFMT_U8 /* | AFMT_S16_LE */,
+ AFMT_STEREO | AFMT_U8 /* AFMT_S16_LE */
+};
+
static pcmchan_caps ess_playcaps = {
5000, 49000,
AFMT_STEREO | AFMT_U8 | AFMT_S16_LE,
@@ -144,16 +151,11 @@ struct sb_chinfo {
struct sb_info {
struct resource *io_base; /* I/O address for the board */
- int io_rid;
struct resource *irq;
- int irq_rid;
- struct resource *drq1; /* play */
- int drq1_rid;
- struct resource *drq2; /* rec */
- int drq2_rid;
+ struct resource *drq1;
+ struct resource *drq2;
bus_dma_tag_t parent_dmat;
- int dma16, dma8;
int bd_id;
u_long bd_flags; /* board-specific flags */
struct sb_chinfo pch, rch;
@@ -166,31 +168,25 @@ static int sb_cmd(struct sb_info *sb, u_char val);
static int sb_cmd1(struct sb_info *sb, u_char cmd, int val);
static int sb_cmd2(struct sb_info *sb, u_char cmd, int val);
static u_int sb_get_byte(struct sb_info *sb);
-static int ess_write(struct sb_info *sb, u_char reg, int val);
-static int ess_read(struct sb_info *sb, u_char reg);
-
-/*
- * in the SB, there is a set of indirect "mixer" registers with
- * address at offset 4, data at offset 5
- */
static void sb_setmixer(struct sb_info *sb, u_int port, u_int value);
static int sb_getmixer(struct sb_info *sb, u_int port);
-
-static void sb_intr(void *arg);
-static void ess_intr(void *arg);
-static int sb_init(device_t dev, struct sb_info *sb);
static int sb_reset_dsp(struct sb_info *sb);
+static void sb_intr(void *arg);
static int sb_format(struct sb_chinfo *ch, u_int32_t format);
static int sb_speed(struct sb_chinfo *ch, int speed);
static int sb_start(struct sb_chinfo *ch);
static int sb_stop(struct sb_chinfo *ch);
+static int ess_write(struct sb_info *sb, u_char reg, int val);
+static int ess_read(struct sb_info *sb, u_char reg);
+static void ess_intr(void *arg);
static int ess_format(struct sb_chinfo *ch, u_int32_t format);
static int ess_speed(struct sb_chinfo *ch, int speed);
static int ess_start(struct sb_chinfo *ch);
static int ess_stop(struct sb_chinfo *ch);
static int ess_abort(struct sb_chinfo *ch);
+
static int sbmix_init(snd_mixer *m);
static int sbmix_set(snd_mixer *m, unsigned dev, unsigned left, unsigned right);
static int sbmix_setrecsrc(snd_mixer *m, u_int32_t src);
@@ -377,20 +373,19 @@ sb_release_resources(struct sb_info *sb, device_t dev)
{
/* should we bus_teardown_intr here? */
if (sb->irq) {
- bus_release_resource(dev, SYS_RES_IRQ, sb->irq_rid, sb->irq);
+ bus_release_resource(dev, SYS_RES_IRQ, 0, sb->irq);
sb->irq = 0;
}
if (sb->drq1) {
- bus_release_resource(dev, SYS_RES_DRQ, sb->drq1_rid, sb->drq1);
+ bus_release_resource(dev, SYS_RES_DRQ, 0, sb->drq1);
sb->drq1 = 0;
}
if (sb->drq2) {
- bus_release_resource(dev, SYS_RES_DRQ, sb->drq2_rid, sb->drq2);
+ bus_release_resource(dev, SYS_RES_DRQ, 1, sb->drq2);
sb->drq2 = 0;
}
if (sb->io_base) {
- bus_release_resource(dev, SYS_RES_IOPORT, sb->io_rid,
- sb->io_base);
+ bus_release_resource(dev, SYS_RES_IOPORT, 0, sb->io_base);
sb->io_base = 0;
}
free(sb, M_DEVBUF);
@@ -399,184 +394,66 @@ sb_release_resources(struct sb_info *sb, device_t dev)
static int
sb_alloc_resources(struct sb_info *sb, device_t dev)
{
+ int rid;
+
+ rid = 0;
if (!sb->io_base)
sb->io_base = bus_alloc_resource(dev, SYS_RES_IOPORT,
- &sb->io_rid, 0, ~0, 1,
+ &rid, 0, ~0, 1,
RF_ACTIVE);
+ rid = 0;
if (!sb->irq)
sb->irq = bus_alloc_resource(dev, SYS_RES_IRQ,
- &sb->irq_rid, 0, ~0, 1,
+ &rid, 0, ~0, 1,
RF_ACTIVE);
+ rid = 0;
if (!sb->drq1)
sb->drq1 = bus_alloc_resource(dev, SYS_RES_DRQ,
- &sb->drq1_rid, 0, ~0, 1,
+ &rid, 0, ~0, 1,
RF_ACTIVE);
- if (!sb->drq2 && sb->drq2_rid > 0)
+ rid = 1;
+ if (!sb->drq2)
sb->drq2 = bus_alloc_resource(dev, SYS_RES_DRQ,
- &sb->drq2_rid, 0, ~0, 1,
+ &rid, 0, ~0, 1,
RF_ACTIVE);
if (sb->io_base && sb->drq1 && sb->irq) {
- sb->dma8 = rman_get_start(sb->drq1);
- isa_dma_acquire(sb->dma8);
- isa_dmainit(sb->dma8, DSP_BUFFSIZE);
+ isa_dma_acquire(rman_get_start(sb->drq1));
+ isa_dmainit(rman_get_start(sb->drq1), DSP_BUFFSIZE);
if (sb->drq2) {
- sb->dma16 = rman_get_start(sb->drq2);
- isa_dma_acquire(sb->dma16);
- isa_dmainit(sb->dma16, DSP_BUFFSIZE);
- } else sb->dma16 = sb->dma8;
-
- if (sb->dma8 > sb->dma16) {
- int tmp = sb->dma16;
- sb->dma16 = sb->dma8;
- sb->dma8 = tmp;
+ isa_dma_acquire(rman_get_start(sb->drq2));
+ isa_dmainit(rman_get_start(sb->drq2), DSP_BUFFSIZE);
}
+
return 0;
} else return ENXIO;
}
-static int
-sb_identify_board(device_t dev, struct sb_info *sb)
-{
- char *fmt = NULL;
- static char buf[64];
- int essver = 0;
-
- sb_cmd(sb, DSP_CMD_GETVER); /* Get version */
- sb->bd_id = (sb_get_byte(sb) << 8) | sb_get_byte(sb);
-
- switch (sb->bd_id >> 8) {
- case 1: /* old sound blaster has nothing... */
- case 2:
- fmt = "SoundBlaster %d.%d" ; /* default */
- break;
-
- case 3:
- fmt = "SoundBlaster Pro %d.%d";
- if (sb->bd_id == 0x301) {
- int rev;
-
- /* Try to detect ESS chips. */
- sb_cmd(sb, DSP_CMD_GETID); /* Return ident. bytes. */
- essver = (sb_get_byte(sb) << 8) | sb_get_byte(sb);
- rev = essver & 0x000f;
- essver &= 0xfff0;
- if (essver == 0x4880) {
- /* the ESS488 can be treated as an SBPRO */
- fmt = "SoundBlaster Pro (ESS488 rev %d)";
- } else if (essver == 0x6880) {
- if (rev < 8) fmt = "ESS688 rev %d";
- else fmt = "ESS1868 rev %d";
- sb->bd_flags |= BD_F_ESS;
- } else return ENXIO;
- sb->bd_id &= 0xff00;
- sb->bd_id |= ((essver & 0xf000) >> 8) | rev;
- }
- break;
-
- case 4:
- sb->bd_flags |= BD_F_SB16;
- if (sb->bd_flags & BD_F_SB16X) fmt = "SB16 ViBRA16X %d.%d";
- else fmt = "SoundBlaster 16 %d.%d";
- break;
-
- default:
- device_printf(dev, "failed to get SB version (%x)\n",
- sb->bd_id);
- return ENXIO;
- }
- if (essver) snprintf(buf, sizeof buf, fmt, sb->bd_id & 0x000f);
- else snprintf(buf, sizeof buf, fmt, sb->bd_id >> 8, sb->bd_id & 0xff);
- device_set_desc_copy(dev, buf);
- return sb_reset_dsp(sb);
-}
-
-static int
-sb_init(device_t dev, struct sb_info *sb)
-{
- int x, irq;
-
- sb->bd_flags &= ~BD_F_MIX_MASK;
- /* do various initializations depending on board id. */
- switch (sb->bd_id >> 8) {
- case 1: /* old sound blaster has nothing... */
- break;
-
- case 2:
- sb->bd_flags |= BD_F_DUP_MIDI;
- if (sb->bd_id > 0x200) sb->bd_flags |= BD_F_MIX_CT1335;
- break;
-
- case 3:
- sb->bd_flags |= BD_F_DUP_MIDI | BD_F_MIX_CT1345;
- break;
-
- case 4:
- sb->bd_flags |= BD_F_SB16 | BD_F_MIX_CT1745;
- if (sb->dma16 != sb->dma8) sb->bd_flags |= BD_F_DUPLEX;
-
- /* soft irq/dma configuration */
- x = -1;
- irq = rman_get_start(sb->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(sb, IRQ_NR, x);
- sb_setmixer(sb, DMA_NR, (1 << sb->dma16) | (1 << sb->dma8));
- break;
- }
- return 0;
-}
-
-static int
-sb_probe(device_t dev)
+static void
+sb16_swap(void *v, int dir)
{
- snddev_info *d = device_get_softc(dev);
- struct sb_info *sb;
- int allocated, i;
- int error;
-
- if (isa_get_vendorid(dev)) return ENXIO; /* not yet */
-
- device_set_desc(dev, "SoundBlaster");
- bzero(d, sizeof *d);
- sb = (struct sb_info *)malloc(sizeof *sb, M_DEVBUF, M_NOWAIT);
- if (!sb) return ENXIO;
- bzero(sb, sizeof *sb);
-
- allocated = 0;
- sb->io_rid = 0;
- sb->io_base = bus_alloc_resource(dev, SYS_RES_IOPORT, &sb->io_rid,
- 0, ~0, 16, RF_ACTIVE);
- if (!sb->io_base) {
- BVDDB(printf("sb_probe: no addr, trying (0x220, 0x240)\n"));
- allocated = 1;
- sb->io_rid = 0;
- sb->io_base = bus_alloc_resource(dev, SYS_RES_IOPORT,
- &sb->io_rid, 0x220, 0x22f,
- 16, RF_ACTIVE);
- if (!sb->io_base) {
- sb->io_base = bus_alloc_resource(dev, SYS_RES_IOPORT,
- &sb->io_rid, 0x240,
- 0x24f, 16, RF_ACTIVE);
+ struct sb_info *sb = v;
+ int pb = sb->pch.buffer->dl;
+ int rb = sb->rch.buffer->dl;
+ int pc = sb->pch.buffer->chan;
+ int rc = sb->rch.buffer->chan;
+ int swp = 0;
+
+ if (!pb && !rb) {
+ if (dir == PCMDIR_PLAY && pc < 4) swp = 1;
+ else if (dir == PCMDIR_REC && rc < 4) swp = 1;
+ if (sb->bd_flags & BD_F_SB16X) swp = !swp;
+ if (swp) {
+ int t;
+
+ t = sb->pch.buffer->chan;
+ sb->pch.buffer->chan = sb->rch.buffer->chan;
+ sb->rch.buffer->chan = t;
+ sb->pch.buffer->dir = B_WRITE;
+ sb->rch.buffer->dir = B_READ;
}
- }
- if (!sb->io_base) return ENXIO;
-
- error = sb_reset_dsp(sb);
- if (error) goto no;
- error = sb_identify_board(dev, sb);
- if (error) goto no;
-no:
- i = sb->io_rid;
- sb_release_resources(sb, dev);
- if (allocated) bus_delete_resource(dev, SYS_RES_IOPORT, i);
- return error;
+ }
}
static int
@@ -584,29 +461,21 @@ sb_doattach(device_t dev, struct sb_info *sb)
{
snddev_info *d = device_get_softc(dev);
void *ih;
- int error;
char status[SND_STATUSLEN];
- sb->irq_rid = 0;
- sb->drq1_rid = 0;
- sb->drq2_rid = 1;
if (sb_alloc_resources(sb, dev)) goto no;
- error = sb_reset_dsp(sb);
- if (error) goto no;
- error = sb_identify_board(dev, sb);
- if (error) goto no;
-
- sb_init(dev, sb);
+ if (sb_reset_dsp(sb)) goto no;
mixer_init(d, &sb_mixer, sb);
+
if (sb->bd_flags & BD_F_ESS)
bus_setup_intr(dev, sb->irq, INTR_TYPE_TTY, ess_intr, sb, &ih);
else
bus_setup_intr(dev, sb->irq, INTR_TYPE_TTY, sb_intr, sb, &ih);
-
- if (sb->bd_flags & BD_F_SB16)
- pcm_setflags(dev, pcm_getflags(dev) | SD_F_EVILSB16);
- if (sb->dma16 == sb->dma8)
+ if ((sb->bd_flags & BD_F_SB16) && !(sb->bd_flags & BD_F_SB16X))
+ pcm_setswap(dev, sb16_swap);
+ if (!sb->drq2)
pcm_setflags(dev, pcm_getflags(dev) | SD_F_SIMPLEX);
+
if (bus_dma_tag_create(/*parent*/NULL, /*alignment*/2, /*boundary*/0,
/*lowaddr*/BUS_SPACE_MAXADDR_24BIT,
/*highaddr*/BUS_SPACE_MAXADDR,
@@ -618,11 +487,11 @@ sb_doattach(device_t dev, struct sb_info *sb)
goto no;
}
- snprintf(status, SND_STATUSLEN, "at io 0x%lx irq %ld drq %d",
+ snprintf(status, SND_STATUSLEN, "at io 0x%lx irq %ld drq %ld",
rman_get_start(sb->io_base), rman_get_start(sb->irq),
- sb->dma8);
- if (sb->dma16 != sb->dma8) snprintf(status + strlen(status),
- SND_STATUSLEN - strlen(status), ":%d", sb->dma16);
+ rman_get_start(sb->drq1));
+ if (sb->drq2) snprintf(status + strlen(status), SND_STATUSLEN - strlen(status),
+ ":%ld", rman_get_start(sb->drq2));
if (pcm_register(dev, sb, 1, 1)) goto no;
if (sb->bd_flags & BD_F_ESS) {
@@ -641,57 +510,6 @@ no:
return ENXIO;
}
-static int
-sb_attach(device_t dev)
-{
- struct sb_info *sb;
- int flags = device_get_flags(dev);
-
- if (flags & DV_F_DUAL_DMA) {
- bus_set_resource(dev, SYS_RES_DRQ, 1,
- flags & DV_F_DRQ_MASK, 1);
- }
- sb = (struct sb_info *)malloc(sizeof *sb, M_DEVBUF, M_NOWAIT);
- if (!sb) return ENXIO;
- bzero(sb, sizeof *sb);
-
- /* XXX in probe should set io resource to right val instead of this */
- sb->io_rid = 0;
- sb->io_base = bus_alloc_resource(dev, SYS_RES_IOPORT, &sb->io_rid,
- 0, ~0, 16, RF_ACTIVE);
- if (!sb->io_base) {
- BVDDB(printf("sb_probe: no addr, trying (0x220, 0x240)\n"));
- sb->io_rid = 0;
- sb->io_base = bus_alloc_resource(dev, SYS_RES_IOPORT,
- &sb->io_rid, 0x220, 0x22f,
- 16, RF_ACTIVE);
- if (!sb->io_base) {
- sb->io_base = bus_alloc_resource(dev, SYS_RES_IOPORT,
- &sb->io_rid, 0x240,
- 0x24f, 16, RF_ACTIVE);
- }
- }
- if (!sb->io_base) return ENXIO;
-
- return sb_doattach(dev, sb);
-}
-
-static device_method_t sb_methods[] = {
- /* Device interface */
- DEVMETHOD(device_probe, sb_probe),
- DEVMETHOD(device_attach, sb_attach),
-
- { 0, 0 }
-};
-
-static driver_t sb_driver = {
- "pcm",
- sb_methods,
- sizeof(snddev_info),
-};
-
-DRIVER_MODULE(sb, isa, sb_driver, pcm_devclass, 0, 0);
-
static void
sb_intr(void *arg)
{
@@ -829,6 +647,7 @@ sb_start(struct sb_chinfo *ch)
int b16 = (ch->fmt & AFMT_S16_LE)? 1 : 0;
int stereo = (ch->fmt & AFMT_STEREO)? 1 : 0;
int l = ch->buffer->dl;
+ int dh = ch->buffer->chan > 3;
u_char i1, i2 = 0;
if (b16) l >>= 1;
@@ -837,7 +656,7 @@ sb_start(struct sb_chinfo *ch)
if (sb->bd_flags & BD_F_SB16) {
i1 = DSP_F16_AUTO | DSP_F16_FIFO_ON |
(play? DSP_F16_DAC : DSP_F16_ADC);
- i1 |= (b16 && (sb->bd_flags & BD_F_DUPLEX))? DSP_DMA16 : DSP_DMA8;
+ i1 |= (b16 || dh)? DSP_DMA16 : DSP_DMA8;
i2 = (stereo? DSP_F16_STEREO : 0) | (b16? DSP_F16_SIGNED : 0);
sb_cmd(sb, i1);
sb_cmd2(sb, i2, l);
@@ -999,7 +818,8 @@ sbchan_init(void *devinfo, snd_dbuf *b, pcm_channel *c, int dir)
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)? sb->dma16 : sb->dma8;
+ ch->buffer->chan = (dir == PCMDIR_PLAY)? rman_get_start(sb->drq2)
+ : rman_get_start(sb->drq1);
return ch;
}
@@ -1053,12 +873,14 @@ sbchan_getcaps(void *data)
{
struct sb_chinfo *ch = data;
int p = (ch->dir == PCMDIR_PLAY)? 1 : 0;
- if (ch->parent->bd_id <= 0x200)
+ if (ch->parent->bd_id < 0x300)
return p? &sb_playcaps : &sb_reccaps;
- else if (ch->parent->bd_id >= 0x400)
- return p? &sb16_playcaps : &sb16_reccaps;
- else
+ else if (ch->parent->bd_id < 0x400)
return p? &sbpro_playcaps : &sbpro_reccaps;
+ else if (ch->parent->bd_flags & BD_F_SB16X)
+ return &sb16x_caps;
+ else
+ return (ch->buffer->chan >= 4)? &sb16_hcaps : &sb16_lcaps;
}
/* channel interface for ESS18xx */
#ifdef notyet
@@ -1253,101 +1075,21 @@ sbmix_setrecsrc(snd_mixer *m, u_int32_t src)
}
static int
-sbpnp_probe(device_t dev)
-{
- char *s = NULL;
- u_int32_t logical_id = isa_get_logicalid(dev);
-
- switch(logical_id) {
- case 0x01000000: /* @@@0001 */
- s = "Avance Asound 100";
- break;
-
- case 0x01100000: /* @@@1001 */
- s = "Avance Asound 110";
- break;
-
- case 0x01200000: /* @@@2001 */
- s = "Avance Logic ALS120";
- break;
-
- case 0x68187316: /* ESS1868 */
- s = "ESS1868";
- break;
-
- case 0x69187316: /* ESS1869 */
- case 0xacb0110e: /* Compaq's Presario 1621 ESS1869 */
- s = "ESS1869";
- break;
-
- case 0x79187316: /* ESS1879 */
- s = "ESS1879";
- break;
-
- case 0x88187316: /* ESS1888 */
- s = "ESS1888";
- break;
- }
- if (s) {
- device_set_desc(dev, s);
- return (0);
- }
- return ENXIO;
-}
-
-static int
-sbpnp_attach(device_t dev)
-{
- struct sb_info *sb;
- u_int32_t vend_id = isa_get_vendorid(dev);
-
- sb = (struct sb_info *)malloc(sizeof *sb, M_DEVBUF, M_NOWAIT);
- if (!sb) return ENXIO;
- bzero(sb, sizeof *sb);
-
- switch(vend_id) {
- case 0xf0008c0e:
- case 0x10019305:
- case 0x20019305:
- /* XXX add here the vend_id for other vibra16X cards... */
- sb->bd_flags = BD_F_SB16X;
- }
- return sb_doattach(dev, sb);
-}
-
-static device_method_t sbpnp_methods[] = {
- /* Device interface */
- DEVMETHOD(device_probe, sbpnp_probe),
- DEVMETHOD(device_attach, sbpnp_attach),
-
- { 0, 0 }
-};
-
-static driver_t sbpnp_driver = {
- "pcm",
- sbpnp_methods,
- sizeof(snddev_info),
-};
-
-DRIVER_MODULE(sbpnp, isa, sbpnp_driver, pcm_devclass, 0, 0);
-
-#if NSBC > 0
-#define DESCSTR " PCM Audio"
-static int
sbsbc_probe(device_t dev)
{
- char *s = NULL;
- struct sndcard_func *func;
+ char buf[64];
+ u_int32_t func, ver, r;
/* The parent device has already been probed. */
-
- func = device_get_ivars(dev);
- if (func == NULL || func->func != SCF_PCM)
+ r = BUS_READ_IVAR(device_get_parent(dev), dev, 0, &func);
+ if (func != SCF_PCM)
return (ENXIO);
- s = "SB PCM Audio";
+ r = BUS_READ_IVAR(device_get_parent(dev), dev, 1, &ver);
+ ver &= 0x0000ffff;
+ snprintf(buf, sizeof buf, "SB DSP %d.%02d", ver >> 8, ver & 0xff);
+ device_set_desc_copy(dev, buf);
- device_set_desc(dev, s);
return 0;
}
@@ -1355,22 +1097,16 @@ static int
sbsbc_attach(device_t dev)
{
struct sb_info *sb;
- u_int32_t vend_id;
- device_t sbc;
+ u_int32_t ver;
- sbc = device_get_parent(dev);
- vend_id = isa_get_vendorid(sbc);
sb = (struct sb_info *)malloc(sizeof *sb, M_DEVBUF, M_NOWAIT);
if (!sb) return ENXIO;
bzero(sb, sizeof *sb);
- switch(vend_id) {
- case 0xf0008c0e:
- case 0x10019305:
- case 0x20019305:
- /* XXX add here the vend_id for other vibra16X cards... */
- sb->bd_flags = BD_F_SB16X;
- }
+ BUS_READ_IVAR(device_get_parent(dev), dev, 1, &ver);
+ sb->bd_id = ver & 0x0000ffff;
+ sb->bd_flags = (ver & 0xffff0000) >> 16;
+
return sb_doattach(dev, sb);
}
@@ -1390,4 +1126,5 @@ static driver_t sbsbc_driver = {
DRIVER_MODULE(sbsbc, sbc, sbsbc_driver, pcm_devclass, 0, 0);
-#endif /* NSBC > 0 */
+
+
diff --git a/sys/dev/sound/isa/sb8.c b/sys/dev/sound/isa/sb8.c
index 6aba674..ef55248 100644
--- a/sys/dev/sound/isa/sb8.c
+++ b/sys/dev/sound/isa/sb8.c
@@ -60,6 +60,7 @@ static int esschan_setblocksize(void *data, u_int32_t blocksize);
static int esschan_trigger(void *data, int go);
static int esschan_getptr(void *data);
static pcmchan_caps *esschan_getcaps(void *data);
+
static pcmchan_caps sb_playcaps = {
4000, 22050,
AFMT_U8,
@@ -84,18 +85,24 @@ static pcmchan_caps sbpro_reccaps = {
AFMT_STEREO | AFMT_U8
};
-static pcmchan_caps sb16_playcaps = {
+static pcmchan_caps sb16_hcaps = {
5000, 45000,
AFMT_STEREO | AFMT_S16_LE,
AFMT_STEREO | AFMT_S16_LE
};
-static pcmchan_caps sb16_reccaps = {
+static pcmchan_caps sb16_lcaps = {
5000, 45000,
AFMT_STEREO | AFMT_U8,
AFMT_STEREO | AFMT_U8
};
+static pcmchan_caps sb16x_caps = {
+ 5000, 49000,
+ AFMT_STEREO | AFMT_U8 /* | AFMT_S16_LE */,
+ AFMT_STEREO | AFMT_U8 /* AFMT_S16_LE */
+};
+
static pcmchan_caps ess_playcaps = {
5000, 49000,
AFMT_STEREO | AFMT_U8 | AFMT_S16_LE,
@@ -144,16 +151,11 @@ struct sb_chinfo {
struct sb_info {
struct resource *io_base; /* I/O address for the board */
- int io_rid;
struct resource *irq;
- int irq_rid;
- struct resource *drq1; /* play */
- int drq1_rid;
- struct resource *drq2; /* rec */
- int drq2_rid;
+ struct resource *drq1;
+ struct resource *drq2;
bus_dma_tag_t parent_dmat;
- int dma16, dma8;
int bd_id;
u_long bd_flags; /* board-specific flags */
struct sb_chinfo pch, rch;
@@ -166,31 +168,25 @@ static int sb_cmd(struct sb_info *sb, u_char val);
static int sb_cmd1(struct sb_info *sb, u_char cmd, int val);
static int sb_cmd2(struct sb_info *sb, u_char cmd, int val);
static u_int sb_get_byte(struct sb_info *sb);
-static int ess_write(struct sb_info *sb, u_char reg, int val);
-static int ess_read(struct sb_info *sb, u_char reg);
-
-/*
- * in the SB, there is a set of indirect "mixer" registers with
- * address at offset 4, data at offset 5
- */
static void sb_setmixer(struct sb_info *sb, u_int port, u_int value);
static int sb_getmixer(struct sb_info *sb, u_int port);
-
-static void sb_intr(void *arg);
-static void ess_intr(void *arg);
-static int sb_init(device_t dev, struct sb_info *sb);
static int sb_reset_dsp(struct sb_info *sb);
+static void sb_intr(void *arg);
static int sb_format(struct sb_chinfo *ch, u_int32_t format);
static int sb_speed(struct sb_chinfo *ch, int speed);
static int sb_start(struct sb_chinfo *ch);
static int sb_stop(struct sb_chinfo *ch);
+static int ess_write(struct sb_info *sb, u_char reg, int val);
+static int ess_read(struct sb_info *sb, u_char reg);
+static void ess_intr(void *arg);
static int ess_format(struct sb_chinfo *ch, u_int32_t format);
static int ess_speed(struct sb_chinfo *ch, int speed);
static int ess_start(struct sb_chinfo *ch);
static int ess_stop(struct sb_chinfo *ch);
static int ess_abort(struct sb_chinfo *ch);
+
static int sbmix_init(snd_mixer *m);
static int sbmix_set(snd_mixer *m, unsigned dev, unsigned left, unsigned right);
static int sbmix_setrecsrc(snd_mixer *m, u_int32_t src);
@@ -377,20 +373,19 @@ sb_release_resources(struct sb_info *sb, device_t dev)
{
/* should we bus_teardown_intr here? */
if (sb->irq) {
- bus_release_resource(dev, SYS_RES_IRQ, sb->irq_rid, sb->irq);
+ bus_release_resource(dev, SYS_RES_IRQ, 0, sb->irq);
sb->irq = 0;
}
if (sb->drq1) {
- bus_release_resource(dev, SYS_RES_DRQ, sb->drq1_rid, sb->drq1);
+ bus_release_resource(dev, SYS_RES_DRQ, 0, sb->drq1);
sb->drq1 = 0;
}
if (sb->drq2) {
- bus_release_resource(dev, SYS_RES_DRQ, sb->drq2_rid, sb->drq2);
+ bus_release_resource(dev, SYS_RES_DRQ, 1, sb->drq2);
sb->drq2 = 0;
}
if (sb->io_base) {
- bus_release_resource(dev, SYS_RES_IOPORT, sb->io_rid,
- sb->io_base);
+ bus_release_resource(dev, SYS_RES_IOPORT, 0, sb->io_base);
sb->io_base = 0;
}
free(sb, M_DEVBUF);
@@ -399,184 +394,66 @@ sb_release_resources(struct sb_info *sb, device_t dev)
static int
sb_alloc_resources(struct sb_info *sb, device_t dev)
{
+ int rid;
+
+ rid = 0;
if (!sb->io_base)
sb->io_base = bus_alloc_resource(dev, SYS_RES_IOPORT,
- &sb->io_rid, 0, ~0, 1,
+ &rid, 0, ~0, 1,
RF_ACTIVE);
+ rid = 0;
if (!sb->irq)
sb->irq = bus_alloc_resource(dev, SYS_RES_IRQ,
- &sb->irq_rid, 0, ~0, 1,
+ &rid, 0, ~0, 1,
RF_ACTIVE);
+ rid = 0;
if (!sb->drq1)
sb->drq1 = bus_alloc_resource(dev, SYS_RES_DRQ,
- &sb->drq1_rid, 0, ~0, 1,
+ &rid, 0, ~0, 1,
RF_ACTIVE);
- if (!sb->drq2 && sb->drq2_rid > 0)
+ rid = 1;
+ if (!sb->drq2)
sb->drq2 = bus_alloc_resource(dev, SYS_RES_DRQ,
- &sb->drq2_rid, 0, ~0, 1,
+ &rid, 0, ~0, 1,
RF_ACTIVE);
if (sb->io_base && sb->drq1 && sb->irq) {
- sb->dma8 = rman_get_start(sb->drq1);
- isa_dma_acquire(sb->dma8);
- isa_dmainit(sb->dma8, DSP_BUFFSIZE);
+ isa_dma_acquire(rman_get_start(sb->drq1));
+ isa_dmainit(rman_get_start(sb->drq1), DSP_BUFFSIZE);
if (sb->drq2) {
- sb->dma16 = rman_get_start(sb->drq2);
- isa_dma_acquire(sb->dma16);
- isa_dmainit(sb->dma16, DSP_BUFFSIZE);
- } else sb->dma16 = sb->dma8;
-
- if (sb->dma8 > sb->dma16) {
- int tmp = sb->dma16;
- sb->dma16 = sb->dma8;
- sb->dma8 = tmp;
+ isa_dma_acquire(rman_get_start(sb->drq2));
+ isa_dmainit(rman_get_start(sb->drq2), DSP_BUFFSIZE);
}
+
return 0;
} else return ENXIO;
}
-static int
-sb_identify_board(device_t dev, struct sb_info *sb)
-{
- char *fmt = NULL;
- static char buf[64];
- int essver = 0;
-
- sb_cmd(sb, DSP_CMD_GETVER); /* Get version */
- sb->bd_id = (sb_get_byte(sb) << 8) | sb_get_byte(sb);
-
- switch (sb->bd_id >> 8) {
- case 1: /* old sound blaster has nothing... */
- case 2:
- fmt = "SoundBlaster %d.%d" ; /* default */
- break;
-
- case 3:
- fmt = "SoundBlaster Pro %d.%d";
- if (sb->bd_id == 0x301) {
- int rev;
-
- /* Try to detect ESS chips. */
- sb_cmd(sb, DSP_CMD_GETID); /* Return ident. bytes. */
- essver = (sb_get_byte(sb) << 8) | sb_get_byte(sb);
- rev = essver & 0x000f;
- essver &= 0xfff0;
- if (essver == 0x4880) {
- /* the ESS488 can be treated as an SBPRO */
- fmt = "SoundBlaster Pro (ESS488 rev %d)";
- } else if (essver == 0x6880) {
- if (rev < 8) fmt = "ESS688 rev %d";
- else fmt = "ESS1868 rev %d";
- sb->bd_flags |= BD_F_ESS;
- } else return ENXIO;
- sb->bd_id &= 0xff00;
- sb->bd_id |= ((essver & 0xf000) >> 8) | rev;
- }
- break;
-
- case 4:
- sb->bd_flags |= BD_F_SB16;
- if (sb->bd_flags & BD_F_SB16X) fmt = "SB16 ViBRA16X %d.%d";
- else fmt = "SoundBlaster 16 %d.%d";
- break;
-
- default:
- device_printf(dev, "failed to get SB version (%x)\n",
- sb->bd_id);
- return ENXIO;
- }
- if (essver) snprintf(buf, sizeof buf, fmt, sb->bd_id & 0x000f);
- else snprintf(buf, sizeof buf, fmt, sb->bd_id >> 8, sb->bd_id & 0xff);
- device_set_desc_copy(dev, buf);
- return sb_reset_dsp(sb);
-}
-
-static int
-sb_init(device_t dev, struct sb_info *sb)
-{
- int x, irq;
-
- sb->bd_flags &= ~BD_F_MIX_MASK;
- /* do various initializations depending on board id. */
- switch (sb->bd_id >> 8) {
- case 1: /* old sound blaster has nothing... */
- break;
-
- case 2:
- sb->bd_flags |= BD_F_DUP_MIDI;
- if (sb->bd_id > 0x200) sb->bd_flags |= BD_F_MIX_CT1335;
- break;
-
- case 3:
- sb->bd_flags |= BD_F_DUP_MIDI | BD_F_MIX_CT1345;
- break;
-
- case 4:
- sb->bd_flags |= BD_F_SB16 | BD_F_MIX_CT1745;
- if (sb->dma16 != sb->dma8) sb->bd_flags |= BD_F_DUPLEX;
-
- /* soft irq/dma configuration */
- x = -1;
- irq = rman_get_start(sb->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(sb, IRQ_NR, x);
- sb_setmixer(sb, DMA_NR, (1 << sb->dma16) | (1 << sb->dma8));
- break;
- }
- return 0;
-}
-
-static int
-sb_probe(device_t dev)
+static void
+sb16_swap(void *v, int dir)
{
- snddev_info *d = device_get_softc(dev);
- struct sb_info *sb;
- int allocated, i;
- int error;
-
- if (isa_get_vendorid(dev)) return ENXIO; /* not yet */
-
- device_set_desc(dev, "SoundBlaster");
- bzero(d, sizeof *d);
- sb = (struct sb_info *)malloc(sizeof *sb, M_DEVBUF, M_NOWAIT);
- if (!sb) return ENXIO;
- bzero(sb, sizeof *sb);
-
- allocated = 0;
- sb->io_rid = 0;
- sb->io_base = bus_alloc_resource(dev, SYS_RES_IOPORT, &sb->io_rid,
- 0, ~0, 16, RF_ACTIVE);
- if (!sb->io_base) {
- BVDDB(printf("sb_probe: no addr, trying (0x220, 0x240)\n"));
- allocated = 1;
- sb->io_rid = 0;
- sb->io_base = bus_alloc_resource(dev, SYS_RES_IOPORT,
- &sb->io_rid, 0x220, 0x22f,
- 16, RF_ACTIVE);
- if (!sb->io_base) {
- sb->io_base = bus_alloc_resource(dev, SYS_RES_IOPORT,
- &sb->io_rid, 0x240,
- 0x24f, 16, RF_ACTIVE);
+ struct sb_info *sb = v;
+ int pb = sb->pch.buffer->dl;
+ int rb = sb->rch.buffer->dl;
+ int pc = sb->pch.buffer->chan;
+ int rc = sb->rch.buffer->chan;
+ int swp = 0;
+
+ if (!pb && !rb) {
+ if (dir == PCMDIR_PLAY && pc < 4) swp = 1;
+ else if (dir == PCMDIR_REC && rc < 4) swp = 1;
+ if (sb->bd_flags & BD_F_SB16X) swp = !swp;
+ if (swp) {
+ int t;
+
+ t = sb->pch.buffer->chan;
+ sb->pch.buffer->chan = sb->rch.buffer->chan;
+ sb->rch.buffer->chan = t;
+ sb->pch.buffer->dir = B_WRITE;
+ sb->rch.buffer->dir = B_READ;
}
- }
- if (!sb->io_base) return ENXIO;
-
- error = sb_reset_dsp(sb);
- if (error) goto no;
- error = sb_identify_board(dev, sb);
- if (error) goto no;
-no:
- i = sb->io_rid;
- sb_release_resources(sb, dev);
- if (allocated) bus_delete_resource(dev, SYS_RES_IOPORT, i);
- return error;
+ }
}
static int
@@ -584,29 +461,21 @@ sb_doattach(device_t dev, struct sb_info *sb)
{
snddev_info *d = device_get_softc(dev);
void *ih;
- int error;
char status[SND_STATUSLEN];
- sb->irq_rid = 0;
- sb->drq1_rid = 0;
- sb->drq2_rid = 1;
if (sb_alloc_resources(sb, dev)) goto no;
- error = sb_reset_dsp(sb);
- if (error) goto no;
- error = sb_identify_board(dev, sb);
- if (error) goto no;
-
- sb_init(dev, sb);
+ if (sb_reset_dsp(sb)) goto no;
mixer_init(d, &sb_mixer, sb);
+
if (sb->bd_flags & BD_F_ESS)
bus_setup_intr(dev, sb->irq, INTR_TYPE_TTY, ess_intr, sb, &ih);
else
bus_setup_intr(dev, sb->irq, INTR_TYPE_TTY, sb_intr, sb, &ih);
-
- if (sb->bd_flags & BD_F_SB16)
- pcm_setflags(dev, pcm_getflags(dev) | SD_F_EVILSB16);
- if (sb->dma16 == sb->dma8)
+ if ((sb->bd_flags & BD_F_SB16) && !(sb->bd_flags & BD_F_SB16X))
+ pcm_setswap(dev, sb16_swap);
+ if (!sb->drq2)
pcm_setflags(dev, pcm_getflags(dev) | SD_F_SIMPLEX);
+
if (bus_dma_tag_create(/*parent*/NULL, /*alignment*/2, /*boundary*/0,
/*lowaddr*/BUS_SPACE_MAXADDR_24BIT,
/*highaddr*/BUS_SPACE_MAXADDR,
@@ -618,11 +487,11 @@ sb_doattach(device_t dev, struct sb_info *sb)
goto no;
}
- snprintf(status, SND_STATUSLEN, "at io 0x%lx irq %ld drq %d",
+ snprintf(status, SND_STATUSLEN, "at io 0x%lx irq %ld drq %ld",
rman_get_start(sb->io_base), rman_get_start(sb->irq),
- sb->dma8);
- if (sb->dma16 != sb->dma8) snprintf(status + strlen(status),
- SND_STATUSLEN - strlen(status), ":%d", sb->dma16);
+ rman_get_start(sb->drq1));
+ if (sb->drq2) snprintf(status + strlen(status), SND_STATUSLEN - strlen(status),
+ ":%ld", rman_get_start(sb->drq2));
if (pcm_register(dev, sb, 1, 1)) goto no;
if (sb->bd_flags & BD_F_ESS) {
@@ -641,57 +510,6 @@ no:
return ENXIO;
}
-static int
-sb_attach(device_t dev)
-{
- struct sb_info *sb;
- int flags = device_get_flags(dev);
-
- if (flags & DV_F_DUAL_DMA) {
- bus_set_resource(dev, SYS_RES_DRQ, 1,
- flags & DV_F_DRQ_MASK, 1);
- }
- sb = (struct sb_info *)malloc(sizeof *sb, M_DEVBUF, M_NOWAIT);
- if (!sb) return ENXIO;
- bzero(sb, sizeof *sb);
-
- /* XXX in probe should set io resource to right val instead of this */
- sb->io_rid = 0;
- sb->io_base = bus_alloc_resource(dev, SYS_RES_IOPORT, &sb->io_rid,
- 0, ~0, 16, RF_ACTIVE);
- if (!sb->io_base) {
- BVDDB(printf("sb_probe: no addr, trying (0x220, 0x240)\n"));
- sb->io_rid = 0;
- sb->io_base = bus_alloc_resource(dev, SYS_RES_IOPORT,
- &sb->io_rid, 0x220, 0x22f,
- 16, RF_ACTIVE);
- if (!sb->io_base) {
- sb->io_base = bus_alloc_resource(dev, SYS_RES_IOPORT,
- &sb->io_rid, 0x240,
- 0x24f, 16, RF_ACTIVE);
- }
- }
- if (!sb->io_base) return ENXIO;
-
- return sb_doattach(dev, sb);
-}
-
-static device_method_t sb_methods[] = {
- /* Device interface */
- DEVMETHOD(device_probe, sb_probe),
- DEVMETHOD(device_attach, sb_attach),
-
- { 0, 0 }
-};
-
-static driver_t sb_driver = {
- "pcm",
- sb_methods,
- sizeof(snddev_info),
-};
-
-DRIVER_MODULE(sb, isa, sb_driver, pcm_devclass, 0, 0);
-
static void
sb_intr(void *arg)
{
@@ -829,6 +647,7 @@ sb_start(struct sb_chinfo *ch)
int b16 = (ch->fmt & AFMT_S16_LE)? 1 : 0;
int stereo = (ch->fmt & AFMT_STEREO)? 1 : 0;
int l = ch->buffer->dl;
+ int dh = ch->buffer->chan > 3;
u_char i1, i2 = 0;
if (b16) l >>= 1;
@@ -837,7 +656,7 @@ sb_start(struct sb_chinfo *ch)
if (sb->bd_flags & BD_F_SB16) {
i1 = DSP_F16_AUTO | DSP_F16_FIFO_ON |
(play? DSP_F16_DAC : DSP_F16_ADC);
- i1 |= (b16 && (sb->bd_flags & BD_F_DUPLEX))? DSP_DMA16 : DSP_DMA8;
+ i1 |= (b16 || dh)? DSP_DMA16 : DSP_DMA8;
i2 = (stereo? DSP_F16_STEREO : 0) | (b16? DSP_F16_SIGNED : 0);
sb_cmd(sb, i1);
sb_cmd2(sb, i2, l);
@@ -999,7 +818,8 @@ sbchan_init(void *devinfo, snd_dbuf *b, pcm_channel *c, int dir)
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)? sb->dma16 : sb->dma8;
+ ch->buffer->chan = (dir == PCMDIR_PLAY)? rman_get_start(sb->drq2)
+ : rman_get_start(sb->drq1);
return ch;
}
@@ -1053,12 +873,14 @@ sbchan_getcaps(void *data)
{
struct sb_chinfo *ch = data;
int p = (ch->dir == PCMDIR_PLAY)? 1 : 0;
- if (ch->parent->bd_id <= 0x200)
+ if (ch->parent->bd_id < 0x300)
return p? &sb_playcaps : &sb_reccaps;
- else if (ch->parent->bd_id >= 0x400)
- return p? &sb16_playcaps : &sb16_reccaps;
- else
+ else if (ch->parent->bd_id < 0x400)
return p? &sbpro_playcaps : &sbpro_reccaps;
+ else if (ch->parent->bd_flags & BD_F_SB16X)
+ return &sb16x_caps;
+ else
+ return (ch->buffer->chan >= 4)? &sb16_hcaps : &sb16_lcaps;
}
/* channel interface for ESS18xx */
#ifdef notyet
@@ -1253,101 +1075,21 @@ sbmix_setrecsrc(snd_mixer *m, u_int32_t src)
}
static int
-sbpnp_probe(device_t dev)
-{
- char *s = NULL;
- u_int32_t logical_id = isa_get_logicalid(dev);
-
- switch(logical_id) {
- case 0x01000000: /* @@@0001 */
- s = "Avance Asound 100";
- break;
-
- case 0x01100000: /* @@@1001 */
- s = "Avance Asound 110";
- break;
-
- case 0x01200000: /* @@@2001 */
- s = "Avance Logic ALS120";
- break;
-
- case 0x68187316: /* ESS1868 */
- s = "ESS1868";
- break;
-
- case 0x69187316: /* ESS1869 */
- case 0xacb0110e: /* Compaq's Presario 1621 ESS1869 */
- s = "ESS1869";
- break;
-
- case 0x79187316: /* ESS1879 */
- s = "ESS1879";
- break;
-
- case 0x88187316: /* ESS1888 */
- s = "ESS1888";
- break;
- }
- if (s) {
- device_set_desc(dev, s);
- return (0);
- }
- return ENXIO;
-}
-
-static int
-sbpnp_attach(device_t dev)
-{
- struct sb_info *sb;
- u_int32_t vend_id = isa_get_vendorid(dev);
-
- sb = (struct sb_info *)malloc(sizeof *sb, M_DEVBUF, M_NOWAIT);
- if (!sb) return ENXIO;
- bzero(sb, sizeof *sb);
-
- switch(vend_id) {
- case 0xf0008c0e:
- case 0x10019305:
- case 0x20019305:
- /* XXX add here the vend_id for other vibra16X cards... */
- sb->bd_flags = BD_F_SB16X;
- }
- return sb_doattach(dev, sb);
-}
-
-static device_method_t sbpnp_methods[] = {
- /* Device interface */
- DEVMETHOD(device_probe, sbpnp_probe),
- DEVMETHOD(device_attach, sbpnp_attach),
-
- { 0, 0 }
-};
-
-static driver_t sbpnp_driver = {
- "pcm",
- sbpnp_methods,
- sizeof(snddev_info),
-};
-
-DRIVER_MODULE(sbpnp, isa, sbpnp_driver, pcm_devclass, 0, 0);
-
-#if NSBC > 0
-#define DESCSTR " PCM Audio"
-static int
sbsbc_probe(device_t dev)
{
- char *s = NULL;
- struct sndcard_func *func;
+ char buf[64];
+ u_int32_t func, ver, r;
/* The parent device has already been probed. */
-
- func = device_get_ivars(dev);
- if (func == NULL || func->func != SCF_PCM)
+ r = BUS_READ_IVAR(device_get_parent(dev), dev, 0, &func);
+ if (func != SCF_PCM)
return (ENXIO);
- s = "SB PCM Audio";
+ r = BUS_READ_IVAR(device_get_parent(dev), dev, 1, &ver);
+ ver &= 0x0000ffff;
+ snprintf(buf, sizeof buf, "SB DSP %d.%02d", ver >> 8, ver & 0xff);
+ device_set_desc_copy(dev, buf);
- device_set_desc(dev, s);
return 0;
}
@@ -1355,22 +1097,16 @@ static int
sbsbc_attach(device_t dev)
{
struct sb_info *sb;
- u_int32_t vend_id;
- device_t sbc;
+ u_int32_t ver;
- sbc = device_get_parent(dev);
- vend_id = isa_get_vendorid(sbc);
sb = (struct sb_info *)malloc(sizeof *sb, M_DEVBUF, M_NOWAIT);
if (!sb) return ENXIO;
bzero(sb, sizeof *sb);
- switch(vend_id) {
- case 0xf0008c0e:
- case 0x10019305:
- case 0x20019305:
- /* XXX add here the vend_id for other vibra16X cards... */
- sb->bd_flags = BD_F_SB16X;
- }
+ BUS_READ_IVAR(device_get_parent(dev), dev, 1, &ver);
+ sb->bd_id = ver & 0x0000ffff;
+ sb->bd_flags = (ver & 0xffff0000) >> 16;
+
return sb_doattach(dev, sb);
}
@@ -1390,4 +1126,5 @@ static driver_t sbsbc_driver = {
DRIVER_MODULE(sbsbc, sbc, sbsbc_driver, pcm_devclass, 0, 0);
-#endif /* NSBC > 0 */
+
+
diff --git a/sys/dev/sound/isa/sbc.c b/sys/dev/sound/isa/sbc.c
index 67a367c..01d6c6b 100644
--- a/sys/dev/sound/isa/sbc.c
+++ b/sys/dev/sound/isa/sbc.c
@@ -28,114 +28,298 @@
#include "isa.h"
-#include <sys/param.h>
-#include <sys/systm.h>
-#include <sys/kernel.h>
-#include <sys/bus.h>
-#include <sys/malloc.h>
-#include <sys/module.h>
-#include <machine/resource.h>
-#include <machine/bus.h>
-#include <sys/rman.h>
-#include <sys/soundcard.h>
#include <dev/sound/chip.h>
-
-#if NISA > 0
-#include <isa/isavar.h>
-#include <isa/isa_common.h>
-#ifdef __alpha__ /* XXX workaround a stupid warning */
-#include <alpha/isa/isavar.h>
-#endif
-#endif /* NISA > 0 */
+#include <dev/sound/pcm/sound.h>
+#define __SB_MIXER_C__ /* XXX warning... */
+#define SB_NOMIXER
+#include <dev/sound/isa/sb.h>
/* Here is the parameter structure per a device. */
struct sbc_softc {
device_t dev; /* device */
+
int io_rid[3]; /* io port rids */
struct resource *io[3]; /* io port resources */
int io_alloced[3]; /* io port alloc flag */
+
int irq_rid; /* irq rids */
struct resource *irq; /* irq resources */
int irq_alloced; /* irq alloc flag */
+
int drq_rid[2]; /* drq rids */
struct resource *drq[2]; /* drq resources */
int drq_alloced[2]; /* drq alloc flag */
-};
-typedef struct sbc_softc *sc_p;
+ u_int32_t bd_ver;
+};
-#if NISA > 0
static int sbc_probe(device_t dev);
static int sbc_attach(device_t dev);
-#endif /* NISA > 0 */
static struct resource *sbc_alloc_resource(device_t bus, device_t child, int type, int *rid,
- u_long start, u_long end, u_long count, u_int flags);
+ u_long start, u_long end, u_long count, u_int flags);
static int sbc_release_resource(device_t bus, device_t child, int type, int rid,
- struct resource *r);
+ struct resource *r);
-static int alloc_resource(sc_p scp);
-static int release_resource(sc_p scp);
+static int alloc_resource(struct sbc_softc *scp);
+static int release_resource(struct sbc_softc *scp);
static devclass_t sbc_devclass;
-#if NISA > 0
+static int io_range[3] = {0x10, 0x2, 0x4};
+
+static int sb_rd(struct resource *io, int reg);
+static void sb_wr(struct resource *io, int reg, u_int8_t val);
+static int sb_dspready(struct resource *io);
+static int sb_cmd(struct resource *io, u_char val);
+static u_int sb_get_byte(struct resource *io);
+static void sb_setmixer(struct resource *io, u_int port, u_int value);
+
+static int
+sb_rd(struct resource *io, int reg)
+{
+ return bus_space_read_1(rman_get_bustag(io),
+ rman_get_bushandle(io),
+ reg);
+}
+
+static void
+sb_wr(struct resource *io, int reg, u_int8_t val)
+{
+ return bus_space_write_1(rman_get_bustag(io),
+ rman_get_bushandle(io),
+ reg, val);
+}
+
+static int
+sb_dspready(struct resource *io)
+{
+ return ((sb_rd(io, SBDSP_STATUS) & 0x80) == 0);
+}
+
+static int
+sb_dspwr(struct resource *io, u_char val)
+{
+ int i;
+
+ for (i = 0; i < 1000; i++) {
+ if (sb_dspready(io)) {
+ sb_wr(io, SBDSP_CMD, val);
+ return 1;
+ }
+ if (i > 10) DELAY((i > 100)? 1000 : 10);
+ }
+ printf("sb_dspwr(0x%02x) timed out.\n", val);
+ return 0;
+}
+
+static int
+sb_cmd(struct resource *io, u_char val)
+{
+ return sb_dspwr(io, val);
+}
+
+static void
+sb_setmixer(struct resource *io, u_int port, u_int value)
+{
+ u_long flags;
+
+ flags = spltty();
+ sb_wr(io, SB_MIX_ADDR, (u_char) (port & 0xff)); /* Select register */
+ DELAY(10);
+ sb_wr(io, SB_MIX_DATA, (u_char) (value & 0xff));
+ DELAY(10);
+ splx(flags);
+}
+
+static u_int
+sb_get_byte(struct resource *io)
+{
+ int i;
+
+ for (i = 1000; i > 0; i--) {
+ if (sb_rd(io, DSP_DATA_AVAIL) & 0x80)
+ return sb_rd(io, DSP_READ);
+ else
+ DELAY(20);
+ }
+ return 0xffff;
+}
+
+static int
+sb_reset_dsp(struct resource *io)
+{
+ sb_wr(io, SBDSP_RST, 3);
+ DELAY(100);
+ sb_wr(io, SBDSP_RST, 0);
+ return (sb_get_byte(io) == 0xAA)? 0 : ENXIO;
+}
+
+static int
+sb_identify_board(struct resource *io)
+{
+ int ver, essver, rev;
+
+ sb_cmd(io, DSP_CMD_GETVER); /* Get version */
+ ver = (sb_get_byte(io) << 8) | sb_get_byte(io);
+ if (ver < 0x100 || ver > 0x4ff) return 0;
+ if (ver == 0x0301) {
+ /* Try to detect ESS chips. */
+ sb_cmd(io, DSP_CMD_GETID); /* Return ident. bytes. */
+ essver = (sb_get_byte(io) << 8) | sb_get_byte(io);
+ rev = essver & 0x000f;
+ essver &= 0xfff0;
+ if (essver == 0x4880) ver |= 0x1000;
+ else if (essver == 0x6880) ver = 0x0500 | rev;
+ }
+ return ver;
+}
+
static struct isa_pnp_id sbc_ids[] = {
-#if notdef
- {0x0000630e, "CS423x"},
-#endif
- {0x01008c0e, "Creative ViBRA16C PnP"},
- {0x41008c0e, "Creative ViBRA16CL PnP"},
- {0x43008c0e, "Creative ViBRA16X PnP"},
- {0x31008c0e, "Creative SB16 PnP/SB32"},
+ {0x01008c0e, "Creative ViBRA16C"},
+ {0x31008c0e, "Creative SB16/SB32"},
+ {0x41008c0e, "Creative SB16/SB32"},
{0x42008c0e, "Creative SB AWE64"}, /* CTL00c1 */
+ {0x43008c0e, "Creative ViBRA16X"},
+ {0x44008c0e, "Creative SB AWE64 Gold"},
{0x45008c0e, "Creative SB AWE64"}, /* CTL0045 */
-#if notdef
- {0x01200001, "Avance Logic ALS120"},
+
+ {0x01000000, "Avance Asound 100"},
{0x01100001, "Avance Asound 110"},
- {0x68187316, "ESS ES1868 Plug and Play AudioDrive"}, /* ESS1868 */
- {0x79187316, "ESS ES1879 Plug and Play AudioDrive"}, /* ESS1879 */
- {0x2100a865, "Yamaha OPL3-SA2/SAX Sound Board"},
- {0x80719304, "Terratec Soundsystem Base 1"},
-#endif
+ {0x01200001, "Avance Logic ALS120"},
+
+ {0x68187316, "ESS ES1868"}, /* ESS1868 */
+ {0x69187316, "ESS ES1869"}, /* ESS1869 */
+ {0xacb0110e, "ESS ES1869 (Compaq OEM)"},
+ {0x79187316, "ESS ES1879"}, /* ESS1879 */
+ {0x88187316, "ESS ES1888"}, /* ESS1888 */
+
{0}
};
static int
sbc_probe(device_t dev)
{
- int error;
-
- /* Check pnp ids */
- error = ISA_PNP_PROBE(device_get_parent(dev), dev, sbc_ids);
- if (error)
- return error;
- else
- return -100;
+ char *s = NULL;
+ u_int32_t logical_id = isa_get_logicalid(dev);
+ if (logical_id) {
+ /* Check pnp ids */
+ return ISA_PNP_PROBE(device_get_parent(dev), dev, sbc_ids);
+ } else {
+ int rid = 0, ver;
+ struct resource *io;
+
+ io = bus_alloc_resource(dev, SYS_RES_IOPORT, &rid,
+ 0, ~0, 16, RF_ACTIVE);
+ if (!io) goto bad;
+ if (sb_reset_dsp(io)) goto bad2;
+ ver = sb_identify_board(io);
+ if (ver == 0) goto bad2;
+ switch ((ver & 0x00000f00) >> 8) {
+ case 1:
+ case 2:
+ s = "Soundblaster";
+ break;
+
+ case 3:
+ s = (ver & 0x0000f000)? "ESS 488" : "Soundblaster Pro";
+ break;
+
+ case 4:
+ s = "Soundblaster 16";
+ break;
+
+ case 5:
+ s = (ver & 0x00000008)? "ESS 688" : "ESS 1688";
+ break;
+ }
+ if (s) device_set_desc(dev, s);
+bad2: bus_release_resource(dev, SYS_RES_IOPORT, rid, io);
+bad: return s? 0 : ENXIO;
+ }
}
static int
sbc_attach(device_t dev)
{
- sc_p scp;
- device_t child;
- int unit;
+ 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;
- scp = device_get_softc(dev);
- unit = device_get_unit(dev);
+ if (!logical_id && (flags & DV_F_DUAL_DMA)) {
+ bus_set_resource(dev, SYS_RES_DRQ, 1,
+ flags & DV_F_DRQ_MASK, 1);
+ }
+ scp = device_get_softc(dev);
bzero(scp, sizeof(*scp));
-
scp->dev = dev;
- if (alloc_resource(scp)) {
- release_resource(scp);
- return (ENXIO);
+ if (alloc_resource(scp)) goto bad;
+
+ if (sb_reset_dsp(scp->io[0])) goto bad;
+ scp->bd_ver = sb_identify_board(scp->io[0]) & 0x00000fff;
+ if (scp->bd_ver == 0) goto bad;
+ switch ((scp->bd_ver & 0x0f00) >> 8) {
+ case 1: /* old sound blaster has nothing... */
+ break;
+
+ case 2:
+ f |= BD_F_DUP_MIDI;
+ if (scp->bd_ver > 0x200) f |= BD_F_MIX_CT1335;
+ break;
+
+ case 5:
+ f |= BD_F_ESS;
+ scp->bd_ver = 0x0301;
+ case 3:
+ f |= BD_F_DUP_MIDI | BD_F_MIX_CT1345;
+ break;
+
+ case 4:
+ f |= BD_F_SB16 | BD_F_MIX_CT1745;
+ if (scp->drq[0]) dl = rman_get_start(scp->drq[0]);
+ 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");
+ }
+ break;
+ }
+
+ switch (logical_id) {
+ case 0x01008c0e: /* CTL0001 */
+ case 0x43008c0e: /* CTL0043 */
+ f |= BD_F_SB16X;
+ break;
}
+ scp->bd_ver |= f << 16;
/* PCM Audio */
func = malloc(sizeof(struct sndcard_func), M_DEVBUF, M_NOWAIT);
- if (func == NULL)
- return (ENOMEM);
+ if (func == NULL) goto bad;
bzero(func, sizeof(*func));
func->func = SCF_PCM;
child = device_add_child(dev, "pcm", -1);
@@ -144,8 +328,7 @@ sbc_attach(device_t dev)
#if notyet
/* Midi Interface */
func = malloc(sizeof(struct sndcard_func), M_DEVBUF, M_NOWAIT);
- if (func == NULL)
- return (ENOMEM);
+ if (func == NULL) goto bad;
bzero(func, sizeof(*func));
func->func = SCF_MIDI;
child = device_add_child(dev, "midi", -1);
@@ -153,25 +336,27 @@ sbc_attach(device_t dev)
/* OPL FM Synthesizer */
func = malloc(sizeof(struct sndcard_func), M_DEVBUF, M_NOWAIT);
- if (func == NULL)
- return (ENOMEM);
+ if (func == NULL) goto bad;
bzero(func, sizeof(*func));
func->func = SCF_SYNTH;
child = device_add_child(dev, "midi", -1);
device_set_ivars(child, func);
#endif /* notyet */
+ /* probe/attach kids */
bus_generic_attach(dev);
return (0);
+
+bad: release_resource(scp);
+ return (ENXIO);
}
-#endif /* NISA > 0 */
static struct resource *
sbc_alloc_resource(device_t bus, device_t child, int type, int *rid,
u_long start, u_long end, u_long count, u_int flags)
{
- sc_p scp;
+ struct sbc_softc *scp;
int *alloced, rid_max, alloced_max;
struct resource **res;
@@ -183,18 +368,18 @@ sbc_alloc_resource(device_t bus, device_t child, int type, int *rid,
rid_max = 2;
alloced_max = 1;
break;
- case SYS_RES_IRQ:
- alloced = &scp->irq_alloced;
- res = &scp->irq;
- rid_max = 0;
- alloced_max = 2; /* pcm and mpu may share the irq. */
- break;
case SYS_RES_DRQ:
alloced = scp->drq_alloced;
res = scp->drq;
rid_max = 1;
alloced_max = 1;
break;
+ case SYS_RES_IRQ:
+ alloced = &scp->irq_alloced;
+ res = &scp->irq;
+ rid_max = 0;
+ alloced_max = 2; /* pcm and mpu may share the irq. */
+ break;
default:
return (NULL);
}
@@ -203,14 +388,14 @@ sbc_alloc_resource(device_t bus, device_t child, int type, int *rid,
return (NULL);
alloced[*rid]++;
- return (res[*rid]);
+ return (res[*rid]);
}
static int
sbc_release_resource(device_t bus, device_t child, int type, int rid,
struct resource *r)
{
- sc_p scp;
+ struct sbc_softc *scp;
int *alloced, rid_max;
scp = device_get_softc(bus);
@@ -219,14 +404,14 @@ sbc_release_resource(device_t bus, device_t child, int type, int rid,
alloced = scp->io_alloced;
rid_max = 2;
break;
- case SYS_RES_IRQ:
- alloced = &scp->irq_alloced;
- rid_max = 0;
- break;
case SYS_RES_DRQ:
alloced = scp->drq_alloced;
rid_max = 1;
break;
+ case SYS_RES_IRQ:
+ alloced = &scp->irq_alloced;
+ rid_max = 0;
+ break;
default:
return (1);
}
@@ -238,9 +423,44 @@ sbc_release_resource(device_t bus, device_t child, int type, int rid,
return (0);
}
-static int io_range[3] = {0x10, 0x4, 0x4};
static int
-alloc_resource(sc_p scp)
+sbc_read_ivar(device_t bus, device_t dev, int index, uintptr_t * result)
+{
+ struct sbc_softc *scp = device_get_softc(bus);
+ struct sndcard_func *func = device_get_ivars(dev);
+
+ switch (index) {
+ case 0:
+ *result = func->func;
+ break;
+
+ case 1:
+ *result = scp->bd_ver;
+ break;
+
+ default:
+ return ENOENT;
+ }
+
+ return 0;
+}
+
+static int
+sbc_write_ivar(device_t bus, device_t dev,
+ int index, uintptr_t value)
+{
+ switch (index) {
+ case 0:
+ case 1:
+ return EINVAL;
+
+ default:
+ return (ENOENT);
+ }
+}
+
+static int
+alloc_resource(struct sbc_softc *scp)
{
int i;
@@ -249,34 +469,34 @@ alloc_resource(sc_p scp)
scp->io_rid[i] = i;
scp->io[i] = bus_alloc_resource(scp->dev, SYS_RES_IOPORT, &scp->io_rid[i],
0, ~0, io_range[i], RF_ACTIVE);
- if (scp->io[i] == NULL)
+ if (i == 0 && scp->io[i] == NULL)
return (1);
scp->io_alloced[i] = 0;
}
}
- if (scp->irq == NULL) {
- scp->irq_rid = 0;
- scp->irq = bus_alloc_resource(scp->dev, SYS_RES_IRQ, &scp->irq_rid,
- 0, ~0, 1, RF_ACTIVE | RF_SHAREABLE);
- if (scp->irq == NULL)
- return (1);
- scp->irq_alloced = 0;
- }
for (i = 0 ; i < sizeof(scp->drq) / sizeof(*scp->drq) ; i++) {
if (scp->drq[i] == NULL) {
scp->drq_rid[i] = i;
scp->drq[i] = bus_alloc_resource(scp->dev, SYS_RES_DRQ, &scp->drq_rid[i],
0, ~0, 1, RF_ACTIVE);
- if (scp->drq[i] == NULL)
+ if (i == 0 && scp->drq[i] == NULL)
return (1);
scp->drq_alloced[i] = 0;
}
}
+ if (scp->irq == NULL) {
+ scp->irq_rid = 0;
+ scp->irq = bus_alloc_resource(scp->dev, SYS_RES_IRQ, &scp->irq_rid,
+ 0, ~0, 1, RF_ACTIVE);
+ if (scp->irq == NULL)
+ return (1);
+ scp->irq_alloced = 0;
+ }
return (0);
}
static int
-release_resource(sc_p scp)
+release_resource(struct sbc_softc *scp)
{
int i;
@@ -299,7 +519,6 @@ release_resource(sc_p scp)
return (0);
}
-#if NISA > 0
static device_method_t sbc_methods[] = {
/* Device interface */
DEVMETHOD(device_probe, sbc_probe),
@@ -310,6 +529,8 @@ static device_method_t sbc_methods[] = {
DEVMETHOD(device_resume, bus_generic_resume),
/* Bus interface */
+ DEVMETHOD(bus_read_ivar, sbc_read_ivar),
+ DEVMETHOD(bus_write_ivar, sbc_write_ivar),
DEVMETHOD(bus_print_child, bus_generic_print_child),
DEVMETHOD(bus_alloc_resource, sbc_alloc_resource),
DEVMETHOD(bus_release_resource, sbc_release_resource),
@@ -327,8 +548,6 @@ static driver_t sbc_driver = {
sizeof(struct sbc_softc),
};
-/*
- * sbc can be attached to an isa bus.
- */
+/* sbc can be attached to an isa bus. */
DRIVER_MODULE(sbc, isa, sbc_driver, sbc_devclass, 0, 0);
-#endif /* NISA > 0 */
+
OpenPOWER on IntegriCloud