sb16.c revision 47536
1/* 2 * sound/sb_dsp.c 3 * 4 * driver for the SoundBlaster and clones. 5 * 6 * Copyright 1997,1998 Luigi Rizzo. 7 * 8 * Derived from files in the Voxware 3.5 distribution, 9 * Copyright by Hannu Savolainen 1994, under the same copyright 10 * conditions. 11 * 12 * Redistribution and use in source and binary forms, with or without 13 * modification, are permitted provided that the following conditions 14 * are met: 15 * 1. Redistributions of source code must retain the above copyright 16 * notice, this list of conditions and the following disclaimer. 17 * 2. Redistributions in binary form must reproduce the above copyright 18 * notice, this list of conditions and the following disclaimer in 19 * the documentation and/or other materials provided with the 20 * distribution. 21 * 22 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' 23 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 24 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A 25 * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR 26 * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 27 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 28 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF 29 * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED 30 * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 31 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN 32 * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 33 * POSSIBILITY OF SUCH DAMAGE. 34 * 35 */ 36 37/* 38 * use this as a template file for board-specific drivers. 39 * The next two lines (and the final #endif) are in all drivers: 40 */ 41 42#include <i386/isa/snd/sound.h> 43#if NPCM > 0 44 45/* 46 * Begin with the board-specific include files... 47 */ 48 49#define __SB_MIXER_C__ /* XXX warning... */ 50#include <i386/isa/snd/sbcard.h> 51 52/* 53 * then prototypes of functions which go in the snddev_info 54 * (usually static, unless they are shared by other modules)... 55 */ 56 57static int sb_probe(struct isa_device *dev); 58static int sb_attach(struct isa_device *dev); 59 60static d_open_t sb_dsp_open; 61static d_close_t sb_dsp_close; 62static d_ioctl_t sb_dsp_ioctl; 63static irq_proc_t sb_intr; 64static snd_callback_t sb_callback; 65 66/* 67 * and prototypes for other private functions defined in this module. 68 */ 69 70static void sb_dsp_init(snddev_info *d, struct isa_device *dev); 71static void sb_mix_init(snddev_info *d); 72static int sb_mixer_set(snddev_info *d, int dev, int value); 73static int dsp_speed(snddev_info *d); 74static void sb_mixer_reset(snddev_info *d); 75 76u_int sb_get_byte(int io_base); 77int ess_write(int io_base, u_char reg, int val); 78int ess_read(int io_base, u_char reg); 79 80/* 81 * Then put here the descriptors for the various boards supported 82 * by this module, properly initialized. 83 */ 84 85snddev_info sb_op_desc = { 86 "basic soundblaster", 87 88 SNDCARD_SB, 89 sb_probe, 90 sb_attach, 91 92 sb_dsp_open, 93 sb_dsp_close /* sb_close */, 94 NULL /* use generic sndread */, 95 NULL /* use generic sndwrite */, 96 sb_dsp_ioctl, 97 sndselect, 98 99 sb_intr, 100 sb_callback, 101 102 DSP_BUFFSIZE, /* bufsize */ 103 104 AFMT_STEREO | AFMT_U8, /* audio format */ 105 106} ; 107 108/* 109 * Then the file continues with the body of all functions 110 * directly referenced in the descriptor. 111 */ 112 113/* 114 * the probe routine for the SoundBlaster only consists in 115 * resetting the dsp and testing if it is there. 116 * Version detection etc. will be done at attach time. 117 * 118 * Remember, ISA probe routines are supposed to return the 119 * size of io space used. 120 */ 121 122static int 123sb_probe(struct isa_device *dev) 124{ 125 bzero(&pcm_info[dev->id_unit], sizeof(pcm_info[dev->id_unit]) ); 126 if (dev->id_iobase == -1) { 127 dev->id_iobase = 0x220; 128 BVDDB(printf("sb_probe: no address supplied, try defaults (0x220,0x240)\n");) 129 if (snd_conflict(dev->id_iobase)) 130 dev->id_iobase = 0x240; 131 } 132 if (snd_conflict(dev->id_iobase)) 133 return 0 ; 134 135 if (sb_reset_dsp(dev->id_iobase)) 136 return 16 ; /* the SB uses 16 registers... */ 137 else 138 return 0; 139} 140 141static int 142sb_attach(struct isa_device *dev) 143{ 144 snddev_info *d = &pcm_info[dev->id_unit] ; 145 146 dev->id_alive = 16 ; /* number of io ports */ 147 /* should be already set but just in case... */ 148 sb_dsp_init(d, dev); 149 return 0 ; 150} 151 152/* 153 * here are the main routines from the switches. 154 */ 155 156/* 157 * Unlike MSS, the sb only supports a single open (does not mean 158 * that only a single process is using it, since it can fork 159 * afterwards, or pass the descriptor to another process). 160 * 161 */ 162static int 163sb_dsp_open(dev_t i_dev, int flags, int mode, struct proc * p) 164{ 165 snddev_info *d; 166 int unit ; 167 int dev; 168 169 dev = minor(i_dev); 170 unit = dev >> 4 ; 171 d = &pcm_info[unit] ; 172 173 DEB(printf("<%s>%d : open\n", d->name, unit)); 174 175 if (d->flags & SND_F_BUSY) { 176 DEB(printf("<%s>%d open: device busy\n", d->name, unit)); 177 return EBUSY ; 178 } 179 180 d->wsel.si_pid = 0; 181 d->wsel.si_flags = 0; 182 183 d->rsel.si_pid = 0; 184 d->rsel.si_flags = 0; 185 186 d->dbuf_out.total = d->dbuf_out.prev_total = 0 ; 187 d->dbuf_in.total = d->dbuf_in.prev_total = 0 ; 188 189 d->flags = 0 ; 190 d->bd_flags &= ~BD_F_HISPEED ; 191 192 switch ( dev & 0xf ) { 193 case SND_DEV_DSP16 : 194 if ((d->audio_fmt & AFMT_S16_LE) == 0) { 195 printf("sorry, 16-bit not supported on SB %d.%02d\n", 196 (d->bd_id >>8) & 0xff, d->bd_id & 0xff); 197 return ENXIO; 198 } 199 d->play_fmt = d->rec_fmt = AFMT_S16_LE ; 200 break; 201 case SND_DEV_AUDIO : 202 d->play_fmt = d->rec_fmt = AFMT_MU_LAW ; 203 break ; 204 case SND_DEV_DSP : 205 d->play_fmt = d->rec_fmt = AFMT_U8 ; 206 break ; 207 } 208 /* 209 * since the SB is not simmetric, I use the open mode to select 210 * which channel should be privileged, and disable I/O in the 211 * other direction. 212 * In case the board is opened RW, we don't have enough 213 * information on what to do. Temporarily, privilege the 214 * playback channel, which is used more often, and set the other 215 * one to U8. 216 */ 217 if ( (flags & FREAD) == 0) /* opened write only */ 218 d->rec_fmt = 0 ; 219 else if ( (flags & FWRITE) == 0) /* opened read only */ 220 d->play_fmt = 0 ; 221 else /* opened read/write */ 222 d->rec_fmt = (d->play_fmt == AFMT_S16_LE) ? AFMT_U8 : AFMT_S16_LE ; 223 224 d->flags |= SND_F_BUSY ; 225 d->play_speed = d->rec_speed = DSP_DEFAULT_SPEED ; 226 227 if (flags & O_NONBLOCK) 228 d->flags |= SND_F_NBIO ; 229 230 sb_reset_dsp(d->io_base); 231 if (d->bd_flags & BD_F_ESS) 232 sb_cmd(d->io_base, 0xc6 ); /* enable extended ESS mode */ 233 ask_init(d); 234 235 return 0; 236} 237 238static int 239sb_dsp_close(dev_t i_dev, int flags, int mode, struct proc * p) 240{ 241 int unit; 242 int dev; 243 snddev_info *d; 244 u_long s; 245 246 dev = minor(i_dev); 247 unit = dev >> 4 ; 248 d = &pcm_info[unit] ; 249 250 s = spltty(); 251 d->flags |= SND_F_CLOSING ; 252 splx(s); 253 snd_flush(d); 254 255 sb_cmd(d->io_base, DSP_CMD_SPKOFF ); /* XXX useless ? */ 256 257 d->flags = 0 ; 258 return 0 ; 259} 260 261static int 262sb_dsp_ioctl(dev_t i_dev, u_long cmd, caddr_t arg, int mode, struct proc * p) 263{ 264 int unit; 265 int dev; 266 snddev_info *d; 267 268 dev = minor(i_dev); 269 unit = dev >> 4 ; 270 d = &pcm_info[unit] ; 271 272 /* 273 * handle mixer calls first. Reads are in the default handler, 274 * so do not bother about them. 275 */ 276 if ( (cmd & MIXER_WRITE(0)) == MIXER_WRITE(0) ) 277 return sb_mixer_set(d, cmd & 0xff, *(int *)arg) ; 278 279 /* 280 * for the remaining functions, use the default handler. 281 * ENOSYS means that the default handler should take care 282 * of implementing the ioctl. 283 */ 284 285 return ENOSYS ; 286} 287 288static void 289sb_intr(int unit) 290{ 291 snddev_info *d = &pcm_info[unit]; 292 int reason = 3, c=1, io_base = d->io_base; 293 294 DEB(printf("got sb_intr for unit %d, flags 0x%08lx\n", unit, d->flags)); 295 296 /* 297 * SB < 4.0 is half duplex and has only 1 bit for int source, 298 * so we fake it. SB 4.x (SB16) has the int source in a separate 299 * register. 300 * The Vibra16X has separate flags for 8 and 16 bit transfers, but 301 * I have no idea how to tell capture from playback interrupts... 302 */ 303#define PLAIN_SB16(x) ( ( (x) & (BD_F_SB16|BD_F_SB16X) ) == BD_F_SB16) 304again: 305 if (d->bd_flags & BD_F_SB16) { 306 c = sb_getmixer(io_base, IRQ_STAT); 307 /* this tells us if the source is 8-bit or 16-bit dma. We 308 * have to check the io channel to map it to read or write... 309 */ 310 reason = 0 ; 311 if ( c & 1 ) { /* 8-bit dma */ 312 if (d->play_fmt == AFMT_U8 || d->play_fmt == AFMT_MU_LAW ) 313 reason |= 1; 314 if (d->rec_fmt == AFMT_U8 || d->rec_fmt == AFMT_MU_LAW ) 315 reason |= 2; 316 } 317 if ( c & 2 ) { /* 16-bit dma */ 318 if (d->play_fmt == AFMT_S16_LE) 319 reason |= 1; 320 if (d->rec_fmt == AFMT_S16_LE) 321 reason |= 2; 322 } 323 } 324 /* XXX previous location of ack... */ 325 DEB(printf("sb_intr, flags 0x%08lx reason %d c 0x%x\n", 326 d->flags, reason, c)); 327 if ( reason & 1 ) { /* possibly a write interrupt */ 328 if ( d->dbuf_out.dl ) 329 dsp_wrintr(d); 330 } 331 if ( reason & 2 ) { 332 if ( d->dbuf_in.dl ) 333 dsp_rdintr(d); 334 } 335 if ( c & 2 ) 336 inb(DSP_DATA_AVL16); /* 16-bit int ack */ 337 if (c & 1) 338 inb(DSP_DATA_AVAIL); /* 8-bit int ack */ 339 340 /* 341 * the sb16 might have multiple sources etc. 342 */ 343 if ((d->bd_flags & BD_F_SB16) && (c & 3)) 344 goto again; 345} 346 347/* 348 * device-specific function called back from the dma module. 349 * The reason of the callback is the second argument. 350 * NOTE: during operations, some ioctl can be called to change 351 * settings (e.g. speed, channels, format), and the default 352 * ioctl handler will just record the change and set the 353 * flag SND_F_INIT. The callback routine is in charge of applying 354 * the changes at the next convenient time (typically, at the 355 * start of operations). For full duplex devices, in some cases the 356 * init requires both channels to be idle. 357 */ 358static int 359sb_callback(snddev_info *d, int reason) 360{ 361 int rd = reason & SND_CB_RD ; 362 snd_dbuf *b = (rd) ? & (d->dbuf_in) : & (d->dbuf_out) ; 363 int l = b->dl ; 364 365 switch (reason & SND_CB_REASON_MASK) { 366 case SND_CB_INIT : /* called with int enabled and no pending io */ 367 /* 368 * set the speed 369 */ 370 dsp_speed(d); 371 /* 372 * set the desired DMA blocksize (influences select behaviour) 373 */ 374 snd_set_blocksize(d); 375 /* 376 * since native mulaw is not present, emulate it. 377 */ 378 if ( (d->play_fmt & AFMT_MU_LAW) || (d->rec_fmt & AFMT_MU_LAW) ) 379 d->flags |= SND_F_XLAT8 ; 380 else 381 d->flags &= ~SND_F_XLAT8 ; 382 383 /* 384 * there are too many flavours of SB for my taste... here i try to do 385 * the proper initialization for each one. 386 */ 387 if (PLAIN_SB16(d->bd_flags)) { 388 389 /* the original SB16 (non-PnP, or PnP, or Vibra16C) 390 * can do full duplex using one 16-bit channel 391 * and one 8-bit channel. It needs to be programmed to 392 * use split format though. 393 * I DON'T do this for the Vibra16X because I have no idea 394 * of what needs to be done there... 395 * 396 * I use the following algorithm: 397 * 1. check which direction(s) are active; 398 * 2. check if we should swap dma channels 399 * 3. check if we can do the swap. 400 */ 401 int swap = 1 ; /* default... */ 402 403 if (d->play_fmt == 0) { 404 /* do whatever the read channel wants */ 405 if ( d->rec_fmt == AFMT_S16_LE && d->dbuf_in.chan > 4 ) 406 swap = 0; 407 if ( d->rec_fmt != AFMT_S16_LE && d->dbuf_in.chan < 4 ) 408 swap = 0; 409 } else { 410 /* privilege the write channel */ 411 if ( d->play_fmt == AFMT_S16_LE && d->dbuf_out.chan > 4 ) 412 swap = 0; 413 if ( d->play_fmt != AFMT_S16_LE && d->dbuf_out.chan < 4 ) 414 swap = 0; 415 if ( d->rec_fmt ) { 416 /* check for possible config errors. 417 * This cannot happen at open time since even in 418 * case of opening rw we privilege the play 419 * channel. 420 */ 421 if (d->rec_fmt == d->play_fmt) { 422 DDB(printf("sorry, read DMA channel unavailable\n")); 423 } 424 } 425 } 426 DEB(printf("sb16: play_fmt %d, rec_fmt %x, swap %d\n", 427 d->play_fmt, d->rec_fmt, swap);) 428 if (swap) { 429 int c = d->dbuf_in.chan ; 430 d->dbuf_in.chan = d->dbuf_out.chan; 431 d->dbuf_out.chan = c ; 432 } 433 } 434 else if (d->bd_flags & BD_F_ESS) { 435 u_char c; 436 437 DEB(printf("SND_CB_INIT, play_fmt == 0x%x, rec_fmt == 0x%x\n", 438 (int) d->play_fmt, (int) d->rec_fmt)); 439 440 /* autoinit DMA mode */ 441 if (d->play_fmt) 442 ess_write(d->io_base, 0xb8, 0x04); 443 else 444 ess_write(d->io_base, 0xb8, 0x0e); 445 446 c = (ess_read(d->io_base, 0xa8) & ~0x03) | 0x01; 447 if ((d->flags & SND_F_STEREO) == 0) 448 c++; 449 ess_write(d->io_base, 0xa8, c); /* select mono/stereo */ 450 ess_write(d->io_base, 0xb9, 2); /* demand 4 bytes/transfer */ 451 452 switch (d->play_fmt ? d->play_fmt : d->rec_fmt) { 453 case AFMT_S16_LE: 454 if (d->flags & SND_F_STEREO) { 455 /* 16 bit stereo */ 456 if (d->play_fmt) 457 ess_write(d->io_base, 0xb6, 0x00); 458 ess_write(d->io_base, 0xb7, 0x71); 459 ess_write(d->io_base, 0xb7, 0xbc); 460 } 461 else { 462 /* 16 bit mono */ 463 if (d->play_fmt) 464 ess_write(d->io_base, 0xb6, 0x00); 465 ess_write(d->io_base, 0xb7, 0x71); 466 ess_write(d->io_base, 0xb7, 0xf4); 467 } 468 break; 469 case AFMT_U8: 470 if (d->flags & SND_F_STEREO) { 471 /* 8 bit stereo */ 472 if (d->play_fmt) 473 ess_write(d->io_base, 0xb6, 0x80); 474 ess_write(d->io_base, 0xb7, 0x51); 475 ess_write(d->io_base, 0xb7, 0x98); 476 } 477 else { 478 /* 8 bit mono */ 479 if (d->play_fmt) 480 ess_write(d->io_base, 0xb6, 0x80); 481 ess_write(d->io_base, 0xb7, 0x51); 482 ess_write(d->io_base, 0xb7, 0xd0); 483 } 484 break; 485 } 486 ess_write(d->io_base, 0xb1, 487 ess_read(d->io_base, 0xb1) | 0x50); 488 ess_write(d->io_base, 0xb2, 489 ess_read(d->io_base, 0xb1) | 0x50); 490 } 491 reset_dbuf(& (d->dbuf_in), SND_CHAN_RD ); 492 reset_dbuf(& (d->dbuf_out), SND_CHAN_WR ); 493 break ; 494 495 case SND_CB_START : /* called with int disabled */ 496 if (d->bd_flags & BD_F_SB16) { 497 u_char c, c1 ; 498 499 if (d->bd_flags & BD_F_SB16X) { 500 /* just a guess: on the Vibra16X, the first 501 * op started takes the first dma channel, 502 * the second one takes the next... 503 * The default is to be ready for play. 504 */ 505 DEB(printf("start %s -- now dma %d:%d\n", 506 rd ? "rd" : "wr", 507 d->dbuf_out.chan, d->dbuf_in.chan);); 508 /* swap only if both channels are idle 509 * play: dl=0, since there is no pause; 510 * rec: rl=0 511 */ 512 if ( rd && d->dbuf_out.dl == 0 && d->dbuf_in.rl == 0 ) { 513 /* must swap channels, but also save dl */ 514 int c = d->dbuf_in.chan ; 515 int dl = d->dbuf_in.dl ; 516 d->dbuf_in.chan = d->dbuf_out.chan; 517 d->dbuf_out.chan = c ; 518 reset_dbuf(& (d->dbuf_in), SND_CHAN_RD ); 519 reset_dbuf(& (d->dbuf_out), SND_CHAN_WR ); 520 d->dbuf_in.dl = dl ; 521 printf("swapped -- now dma %d:%d\n", 522 d->dbuf_out.chan, d->dbuf_in.chan); 523 } 524 } 525 526 /* 527 * XXX note: c1 and l should be set basing on d->rec_fmt, 528 * but there is no choice once a 16 or 8-bit channel 529 * is assigned. This means that if the application 530 * tries to use a bad format, the sound will not be nice. 531 */ 532 if ( b->chan > 4 533 || (rd && d->rec_fmt == AFMT_S16_LE) 534 || (!rd && d->play_fmt == AFMT_S16_LE) 535 ) { 536 c = DSP_F16_AUTO | DSP_F16_FIFO_ON | DSP_DMA16 ; 537 c1 = DSP_F16_SIGNED ; 538 l /= 2 ; 539 } else { 540 c = DSP_F16_AUTO | DSP_F16_FIFO_ON | DSP_DMA8 ; 541 c1 = 0 ; 542 } 543 c |= (rd) ? DSP_F16_ADC : DSP_F16_DAC ; 544 if (d->flags & SND_F_STEREO) 545 c1 |= DSP_F16_STEREO ; 546 547 sb_cmd(d->io_base, c ); 548 sb_cmd3(d->io_base, c1 , l - 1) ; 549 } else if (d->bd_flags & BD_F_ESS) { 550 u_long fmt = rd ? d->rec_fmt : d->play_fmt; 551 552 DEB(printf("SND_CB_START: %s (%d)\n", rd ? "rd" : "wr", l)); 553 if (fmt == AFMT_S16_LE) 554 l >>= 1; 555 l--; 556 if (!rd) 557 sb_cmd(d->io_base, DSP_CMD_SPKON); 558 ess_write(d->io_base, 0xa4, l); 559 ess_write(d->io_base, 0xa5, l >> 8); 560 ess_write(d->io_base, 0xb8, 561 ess_read(d->io_base, 0xb8) | (rd ? 0x0f : 0x05)); 562 } else { /* SBPro -- stereo not supported */ 563 u_char c ; 564 if (!rd) 565 sb_cmd(d->io_base, DSP_CMD_SPKON); 566 /* code for the SB2 and SB3, only MONO */ 567 if (d->bd_flags & BD_F_HISPEED) 568 c = (rd) ? 0x98 : 0x90 ; 569 else 570 c = (rd) ? 0x2c : 0x1c ; 571 if (d->flags & SND_F_STEREO) 572 sb_setmixer(d->io_base, 0xe, 2 ); 573 else 574 sb_setmixer(d->io_base, 0xe, 0 ); 575 /* 576 * some ESS extensions -- they can do 16 bits 577 */ 578 if ( (rd && d->rec_fmt == AFMT_S16_LE) || 579 (!rd && d->play_fmt == AFMT_S16_LE) ) { 580 c |= 1; 581 l /= 2 ; 582 } 583 sb_cmd3(d->io_base, 0x48 , l - 1) ; 584 sb_cmd(d->io_base, c ) ; 585 } 586 break; 587 588 case SND_CB_ABORT : /* XXX */ 589 case SND_CB_STOP : 590 { 591 int cmd = DSP_CMD_DMAPAUSE_8 ; /* default: halt 8 bit chan */ 592 DEB(printf("SND_CB_XXX: reason 0x%x\n", reason)); 593 if ( b->chan > 4 594 || (rd && d->rec_fmt == AFMT_S16_LE) 595 || (!rd && d->play_fmt == AFMT_S16_LE) 596 ) 597 cmd = DSP_CMD_DMAPAUSE_16 ; 598 if (d->bd_flags & BD_F_HISPEED) { 599 sb_reset_dsp(d->io_base); 600 if (d->bd_flags & BD_F_ESS) 601 sb_cmd(d->io_base, 0xc6 ); /* enable extended ESS mode */ 602 d->flags |= SND_F_INIT ; 603 } else { 604 sb_cmd(d->io_base, cmd); /* pause dma. */ 605 /* 606 * The above seems to have the undocumented side effect of 607 * blocking the other side as well. If the other 608 * channel was active (SB16) I have to re-enable it :( 609 */ 610 if ( (rd && d->dbuf_out.dl) || 611 (!rd && d->dbuf_in.dl) ) 612 sb_cmd(d->io_base, cmd == DSP_CMD_DMAPAUSE_8 ? 613 0xd6 : 0xd4); /* continue other dma */ 614 } 615 if (d->bd_flags & BD_F_SB16X) { 616 /* restore possible swapped channels. 617 * The default is to be ready for play. 618 * XXX right now, it kills all input on overflow 619 */ 620 if ( rd && d->dbuf_out.dl == 0 ) { 621 /* must swap channels ? */ 622 int c = d->dbuf_in.chan ; 623 d->dbuf_in.chan = d->dbuf_out.chan; 624 d->dbuf_out.chan = c ; 625 reset_dbuf(& (d->dbuf_in), SND_CHAN_RD ); 626 reset_dbuf(& (d->dbuf_out), SND_CHAN_WR ); 627 printf("restored -- now dma %d:%d\n", 628 d->dbuf_out.chan, d->dbuf_in.chan); 629 } 630 } 631 } 632 DEB( sb_cmd(d->io_base, DSP_CMD_SPKOFF) ); /* speaker off */ 633 break ; 634 635 } 636 return 0 ; 637} 638 639/* 640 * The second part of the file contains all functions specific to 641 * the board and (usually) not exported to other modules. 642 */ 643 644int 645sb_reset_dsp(int io_base) 646{ 647 int loopc; 648 649 outb(io_base + SBDSP_RST, 3); 650 DELAY(100); 651 outb(io_base + SBDSP_RST, 0); 652 for (loopc = 0; loopc<100 && !(inb(DSP_DATA_AVAIL) & 0x80); loopc++) 653 DELAY(30); 654 655 if (inb(DSP_READ) != 0xAA) { 656 DEB(printf("sb_reset_dsp 0x%x failed\n", io_base)); 657 return 0; /* Sorry */ 658 } 659 return 1; 660} 661 662/* 663 * only used in sb_attach from here. 664 */ 665 666static void 667sb_dsp_init(snddev_info *d, struct isa_device *dev) 668{ 669 int i, x; 670 char *fmt = NULL ; 671 int io_base = dev->id_iobase ; 672 673 d->bd_id = 0 ; 674 675 sb_reset_dsp(io_base); 676 sb_cmd(io_base, DSP_CMD_GETVER); /* Get version */ 677 678 for (i = 10000; i; i--) { /* perhaps wait longer on a fast machine ? */ 679 if (inb(DSP_DATA_AVAIL) & 0x80) { /* wait for Data Ready */ 680 if ( (d->bd_id & 0xff00) == 0) 681 d->bd_id = inb(DSP_READ) << 8; /* major */ 682 else { 683 d->bd_id |= inb(DSP_READ); /* minor */ 684 break; 685 } 686 } else 687 DELAY(20); 688 } 689 690 /* 691 * now do various initializations depending on board id. 692 */ 693 694 fmt = "SoundBlaster %d.%d" ; /* default */ 695 696 switch ( d->bd_id >> 8 ) { 697 case 0 : 698 printf("\n\nFailed to get SB version (%x) - possible I/O conflict\n\n", 699 inb(DSP_DATA_AVAIL)); 700 d->bd_id = 0x100; 701 case 1 : /* old sound blaster has nothing... */ 702 break ; 703 704 case 2 : 705 d->dbuf_in.chan = d->dbuf_out.chan ; /* half duplex */ 706 d->bd_flags |= BD_F_DUP_MIDI ; 707 708 if (d->bd_id == 0x200) 709 break ; /* no mixer on the 2.0 */ 710 d->bd_flags &= ~BD_F_MIX_MASK ; 711 d->bd_flags |= BD_F_MIX_CT1335 ; 712 713 break ; 714 case 4 : 715 fmt = "SoundBlaster 16 %d.%d"; 716 d->audio_fmt |= AFMT_FULLDUPLEX | AFMT_WEIRD | AFMT_S8 | AFMT_S16_LE; 717 d->bd_flags |= BD_F_SB16; 718 d->bd_flags &= ~BD_F_MIX_MASK ; 719 d->bd_flags |= BD_F_MIX_CT1745 ; 720 721 /* soft irq/dma configuration */ 722 x = -1 ; 723 if (d->irq == 5) x = 2; 724 else if (d->irq == 7) x = 4; 725 else if (d->irq == 9) x = 1; 726 else if (d->irq == 10) x = 8; 727 if (x == -1) 728 printf("<%s>%d: bad irq %d (only 5,7,9,10 allowed)\n", 729 d->name, dev->id_unit, d->irq); 730 else 731 sb_setmixer(io_base, IRQ_NR, x); 732 if (d->dbuf_out.chan == d->dbuf_in.chan) { 733 printf("WARNING: sb: misconfigured secondary DMA channel\n"); 734 } 735 sb_setmixer(io_base, DMA_NR, (1 << d->dbuf_out.chan) | (1 << d->dbuf_in.chan)); 736 break ; 737 738 case 3 : 739 d->dbuf_in.chan = d->dbuf_out.chan ; /* half duplex */ 740 fmt = "SoundBlaster Pro %d.%d"; 741 d->bd_flags |= BD_F_DUP_MIDI ; 742 d->bd_flags &= ~BD_F_MIX_MASK ; 743 d->bd_flags |= BD_F_MIX_CT1345 ; 744 if (d->bd_id == 0x301) { 745 int ess_major = 0, ess_minor = 0; 746 747 /* 748 * Try to detect ESS chips. 749 */ 750 751 sb_cmd(io_base, DSP_CMD_GETID); /* Return ident. bytes. */ 752 753 for (i = 1000; i; i--) { 754 if (inb(DSP_DATA_AVAIL) & 0x80) { /* wait for Data Ready */ 755 if (ess_major == 0) 756 ess_major = inb(DSP_READ); 757 else { 758 ess_minor = inb(DSP_READ); 759 break; 760 } 761 } else 762 DELAY(20); 763 } 764 765 if (ess_major == 0x48 && (ess_minor & 0xf0) == 0x80) { 766 /* the ESS488 can be treated as an SBPRO */ 767 printf("ESS488 (rev %d)\n", ess_minor & 0x0f); 768 break ; 769 } 770 else if (ess_major == 0x68 && (ess_minor & 0xf0) == 0x80) { 771 int rev = ess_minor & 0xf; 772 773 if (rev >= 8) 774 printf("ESS1868 (rev %d)\n", rev); 775 else 776 printf("ESS688 (rev %d)\n", rev); 777 d->bd_flags |= BD_F_ESS; 778 d->audio_fmt |= AFMT_S16_LE; 779 780 /* enable extended ESS mode */ 781 sb_cmd(d->io_base, 0xc6); 782 break; 783 } else { 784 printf("Unknown card 0x%x 0x%x -- hope it is SBPRO\n", 785 ess_major, ess_minor); 786 break ; 787 } 788 } 789 790 } 791 792 snprintf(d->name, sizeof(d->name), 793 fmt, (d->bd_id >> 8) &0xff, d->bd_id & 0xff); 794 795 sb_mix_init(d); 796} 797 798static void 799sb_mix_init(snddev_info *d) 800{ 801 switch (d->bd_flags & BD_F_MIX_MASK) { 802 case BD_F_MIX_CT1345 : /* SB 3.0 has 1345 mixer */ 803 804 d->mix_devs = SBPRO_MIXER_DEVICES ; 805 d->mix_rec_devs = SBPRO_RECORDING_DEVICES ; 806 d->mix_recsrc = SOUND_MASK_MIC ; 807 808 sb_setmixer(d->io_base, 0, 1 ); /* reset mixer */ 809 sb_setmixer(d->io_base, MIC_VOL , 0x6 ); /* mic volume max */ 810 sb_setmixer(d->io_base, RECORD_SRC , 0x0 ); /* mic source */ 811 sb_setmixer(d->io_base, FM_VOL , 0x0 ); /* no midi */ 812 break ; 813 814 case BD_F_MIX_CT1745 : /* SB16 mixer ... */ 815 816 d->mix_devs = SB16_MIXER_DEVICES ; 817 d->mix_rec_devs = SB16_RECORDING_DEVICES ; 818 d->mix_recsrc = SOUND_MASK_MIC ; 819 } 820 sb_mixer_reset(d); 821} 822 823/* 824 * Common code for the midi and pcm functions 825 * 826 * sb_cmd write a single byte to the CMD port. 827 * sb_cmd2 write a CMD + 1 byte arg 828 * sb_cmd3 write a CMD + 2 byte arg 829 * sb_get_byte returns a single byte from the DSP data port 830 * 831 * ess_write is actually sb_cmd2 832 * ess_read access ext. regs via sb_cmd(0xc0, reg) followed by sb_get_byte 833 */ 834 835int 836sb_cmd(int io_base, u_char val) 837{ 838 int i; 839 840 for (i = 0; i < 1000 ; i++) { 841 if ((inb(io_base + SBDSP_STATUS) & 0x80) == 0) { 842 outb(io_base + SBDSP_CMD, val); 843 return 1; 844 } 845 if (i > 10) 846 DELAY (i > 100 ? 1000 : 10 ); 847 } 848 849 printf("SoundBlaster: DSP Command(0x%02x) timeout. IRQ conflict ?\n", val); 850 return 0; 851} 852 853int 854sb_cmd3(int io_base, u_char cmd, int val) 855{ 856 if (sb_cmd(io_base, cmd)) { 857 sb_cmd(io_base, val & 0xff ); 858 sb_cmd(io_base, (val>>8) & 0xff ); 859 return 1 ; 860 } else 861 return 0; 862} 863 864int 865sb_cmd2(int io_base, u_char cmd, int val) 866{ 867 if (sb_cmd(io_base, cmd)) { 868 sb_cmd(io_base, val & 0xff ); 869 return 1 ; 870 } else 871 return 0; 872} 873 874/* 875 * in the SB, there is a set of indirect "mixer" registers with 876 * address at offset 4, data at offset 5 877 */ 878void 879sb_setmixer(int io_base, u_int port, u_int value) 880{ 881 u_long flags; 882 883 flags = spltty(); 884 outb(io_base + SB_MIX_ADDR, (u_char) (port & 0xff)); /* Select register */ 885 DELAY(10); 886 outb(io_base + SB_MIX_DATA, (u_char) (value & 0xff)); 887 DELAY(10); 888 splx(flags); 889} 890 891int 892sb_getmixer(int io_base, u_int port) 893{ 894 int val; 895 u_long flags; 896 897 flags = spltty(); 898 outb(io_base + SB_MIX_ADDR, (u_char) (port & 0xff)); /* Select register */ 899 DELAY(10); 900 val = inb(io_base + SB_MIX_DATA); 901 DELAY(10); 902 splx(flags); 903 904 return val; 905} 906 907u_int 908sb_get_byte(int io_base) 909{ 910 int i; 911 912 for (i = 1000; i; i--) 913 if (inb(DSP_DATA_AVAIL) & 0x80) 914 return inb(DSP_READ); 915 else 916 DELAY(20); 917 return 0xffff; 918} 919 920int 921ess_write(int io_base, u_char reg, int val) 922{ 923 return sb_cmd2(io_base, reg, val); 924} 925 926int 927ess_read(int io_base, u_char reg) 928{ 929 if (!sb_cmd(io_base, 0xc0) || !sb_cmd(io_base, reg) ) 930 return 0xffff ; 931 return sb_get_byte(io_base); 932} 933 934 935/* 936 * various utility functions for the DSP 937 */ 938 939/* 940 * dsp_speed updates the speed setting from the descriptor. make sure 941 * it is called at spltty(). 942 * Besides, it takes care of stereo setting. 943 */ 944static int 945dsp_speed(snddev_info *d) 946{ 947 u_char tconst; 948 u_long flags; 949 int max_speed = 44100, speed = d->play_speed ; 950 951 /* 952 * special code for the SB16 953 */ 954 if (d->bd_flags & BD_F_SB16) { 955 RANGE (speed, 5000, 45000); 956 d->play_speed = d->rec_speed = speed ; 957 sb_cmd(d->io_base, 0x41); 958 sb_cmd(d->io_base, d->play_speed >> 8 ); 959 sb_cmd(d->io_base, d->play_speed & 0xff ); 960 sb_cmd(d->io_base, 0x42); 961 sb_cmd(d->io_base, d->rec_speed >> 8 ); 962 sb_cmd(d->io_base, d->rec_speed & 0xff ); 963 return speed ; 964 } 965 966 /* 967 * special code for the ESS ... 968 */ 969 if (d->bd_flags & BD_F_ESS) { 970 int t; 971 RANGE (speed, 5000, 49000); 972 if (speed > 22000) { 973 t = (795500 + speed / 2) / speed; 974 speed = (795500 + t / 2) / t ; 975 t = (256 - t ) | 0x80 ; 976 } else { 977 t = (397700 + speed / 2) / speed; 978 speed = (397700 + t / 2) / t ; 979 t = 128 - t ; 980 } 981 ess_write(d->io_base, 0xa1, t); /* set time constant */ 982 d->play_speed = d->rec_speed = speed ; 983 speed = (speed * 9 ) / 20 ; 984 t = 256-7160000/(speed*82); 985 ess_write(d->io_base,0xa2,t); 986 return speed ; 987 } 988 989 /* 990 * This is code for the SB3.x and lower. 991 * Only some models can do stereo, and only if not 992 * simultaneously using midi. 993 * At the moment we do not support either... 994 */ 995#if 0 996 d->flags &= ~SND_F_STEREO; 997#endif 998 999 /* 1000 * here enforce speed limitations. 1001 */ 1002 if (d->bd_id <= 0x200) 1003 max_speed = 22050; /* max 22050 on SB 1.X */ 1004 1005 /* 1006 * SB models earlier than SB Pro have low limit for the 1007 * input rate. Note that this is only for input, but since 1008 * we do not support separate values for rec & play.... 1009 */ 1010 if (d->bd_id <= 0x200) 1011 max_speed = 13000; 1012 else if (d->bd_id < 0x300) 1013 max_speed = 15000; 1014 1015 RANGE(speed, 4000, max_speed); 1016 1017 if (d->flags & SND_F_STEREO) /* really unused right now... */ 1018 speed *= 2; 1019 1020 /* 1021 * Now the speed should be valid. Compute the value to be 1022 * programmed into the board. 1023 */ 1024 1025 if (speed > 22050) { /* High speed mode on 2.01/3.xx */ 1026 int tmp; 1027 1028 tconst = (u_char) ((65536 - ((256000000 + speed / 2) / speed)) >> 8) ; 1029 d->bd_flags |= BD_F_HISPEED ; 1030 1031 flags = spltty(); 1032 sb_cmd2(d->io_base, 0x40, tconst); /* set time constant */ 1033 splx(flags); 1034 1035 tmp = 65536 - (tconst << 8); 1036 speed = (256000000 + tmp / 2) / tmp; 1037 } else { 1038 int tmp; 1039 1040 d->bd_flags &= ~BD_F_HISPEED ; 1041 tconst = (256 - ((1000000 + speed / 2) / speed)) & 0xff; 1042 1043 flags = spltty(); 1044 sb_cmd2(d->io_base, 0x40, tconst); /* set time constant */ 1045 splx(flags); 1046 1047 tmp = 256 - tconst; 1048 speed = (1000000 + tmp / 2) / tmp; 1049 } 1050 1051 if (d->flags & SND_F_STEREO) /* really unused right now... */ 1052 speed /= 2; 1053 1054 d->play_speed = d->rec_speed = speed; 1055 return speed; 1056} 1057 1058/* 1059 * mixer support, originally in sb_mixer.c 1060 */ 1061 1062static void 1063sb_set_recsrc(snddev_info *d, int mask) 1064{ 1065 u_char recdev ; 1066 1067 mask &= d->mix_rec_devs; 1068 switch (d->bd_flags & BD_F_MIX_MASK) { 1069 case BD_F_MIX_CT1345 : 1070 if (mask == SOUND_MASK_LINE) 1071 recdev = 6 ; 1072 else if (mask == SOUND_MASK_CD) 1073 recdev = 2 ; 1074 else { /* default: mic */ 1075 mask = SOUND_MASK_MIC ; 1076 recdev = 0 ; 1077 } 1078 sb_setmixer(d->io_base, RECORD_SRC, 1079 recdev | (sb_getmixer(d->io_base, RECORD_SRC) & ~7 )); 1080 break ; 1081 case BD_F_MIX_CT1745 : /* sb16 */ 1082 if (mask == 0) 1083 mask = SOUND_MASK_MIC ; /* XXX For compatibility. Bug ? */ 1084 recdev = 0 ; 1085 if (mask & SOUND_MASK_MIC) 1086 recdev |= 1 ; 1087 if (mask & SOUND_MASK_CD) 1088 recdev |= 6 ; /* l+r cd */ 1089 if (mask & SOUND_MASK_LINE) 1090 recdev |= 0x18 ; /* l+r line */ 1091 if (mask & SOUND_MASK_SYNTH) 1092 recdev |= 0x60 ; /* l+r midi */ 1093 sb_setmixer(d->io_base, SB16_IMASK_L, recdev); 1094 sb_setmixer(d->io_base, SB16_IMASK_R, recdev); 1095 /* 1096 * since the same volume controls apply to the input and 1097 * output sections, the best approach to have a consistent 1098 * behaviour among cards would be to disable the output path 1099 * on devices which are used to record. 1100 * However, since users like to have feedback, we only disable 1101 * the mike -- permanently. 1102 */ 1103 sb_setmixer(d->io_base, SB16_OMASK, 0x1f & ~1); 1104 break ; 1105 } 1106 d->mix_recsrc = mask; 1107} 1108 1109static void 1110sb_mixer_reset(snddev_info *d) 1111{ 1112 int i; 1113 1114 for (i = 0; i < SOUND_MIXER_NRDEVICES; i++) 1115 sb_mixer_set(d, i, levels[i]); 1116 if (d->bd_flags & BD_F_SB16) { 1117 sb_setmixer(d->io_base, 0x3c, 0x1f); /* make all output active */ 1118 sb_setmixer(d->io_base, 0x3d, 0); /* make all inputs-l off */ 1119 sb_setmixer(d->io_base, 0x3e, 0); /* make all inputs-r off */ 1120 } 1121 sb_set_recsrc(d, SOUND_MASK_MIC); 1122} 1123 1124static int 1125sb_mixer_set(snddev_info *d, int dev, int value) 1126{ 1127 int left = value & 0x000000ff; 1128 int right = (value & 0x0000ff00) >> 8; 1129 int regoffs; 1130 u_char val; 1131 mixer_tab *iomap; 1132 1133#ifdef JAZZ16 1134 if (d->bd_flags & BD_F_JAZZ16 && d->bd_flags & BD_F_JAZZ16_2) 1135 return smw_mixer_set(dev, value); 1136#endif 1137 1138 if (dev == SOUND_MIXER_RECSRC) { 1139 sb_set_recsrc(d, value); 1140 return 0 ; 1141 } 1142 if (left > 100) 1143 left = 100; 1144 if (right > 100) 1145 right = 100; 1146 1147 if (dev > 31) 1148 return EINVAL ; 1149 1150 if (!(d->mix_devs & (1 << dev))) /* Not supported */ 1151 return EINVAL; 1152 1153 switch ( d->bd_flags & BD_F_MIX_MASK ) { 1154 default: 1155 /* mixer unknown, fail... */ 1156 return EINVAL ;/* XXX change this */ 1157 case BD_F_MIX_CT1345 : 1158 iomap = &sbpro_mix ; 1159 break; 1160 case BD_F_MIX_CT1745 : 1161 iomap = &sb16_mix ; 1162 break; 1163 /* XXX how about the SG NX Pro, iomap = sgnxpro_mix */ 1164 } 1165 regoffs = (*iomap)[dev][LEFT_CHN].regno; 1166 if (regoffs == 0) 1167 return EINVAL; 1168 1169 val = sb_getmixer(d->io_base, regoffs); 1170 1171 change_bits(iomap, &val, dev, LEFT_CHN, left); 1172 1173 d->mix_levels[dev] = left | (left << 8); 1174 1175 if ((*iomap)[dev][RIGHT_CHN].regno != regoffs) { /* Change register */ 1176 sb_setmixer(d->io_base, regoffs, val); /* Save the old one */ 1177 regoffs = (*iomap)[dev][RIGHT_CHN].regno; 1178 1179 if (regoffs == 0) 1180 return 0 ; /* Just left channel present */ 1181 1182 val = sb_getmixer(d->io_base, regoffs); /* Read the new one */ 1183 } 1184 change_bits(iomap, &val, dev, RIGHT_CHN, right); 1185 1186 sb_setmixer(d->io_base, regoffs, val); 1187 1188 d->mix_levels[dev] = left | (right << 8); 1189 return 0 ; /* ok */ 1190} 1191 1192/* 1193 * now support for some PnP boards. 1194 */ 1195 1196#if NPNP > 0 1197static char *ess1868_probe(u_long csn, u_long vend_id); 1198static void ess1868_attach(u_long csn, u_long vend_id, char *name, 1199 struct isa_device *dev); 1200 1201static struct pnp_device ess1868 = { 1202 "ESS1868", 1203 ess1868_probe, 1204 ess1868_attach, 1205 &nsnd, /* use this for all sound cards */ 1206 &tty_imask /* imask */ 1207}; 1208DATA_SET (pnpdevice_set, ess1868); 1209 1210static char * 1211ess1868_probe(u_long csn, u_long vend_id) 1212{ 1213 /* 1214 * pnp X 1 os enable drq0 3 irq0 12 port0 0x240 1215 */ 1216 if (vend_id == 0x68187316) { 1217 struct pnp_cinfo d ; 1218 read_pnp_parms ( &d , 1 ) ; 1219 if (d.enable == 0) { 1220 printf("This is an ESS1868, but LDN 1 is disabled\n"); 1221 return NULL; 1222 } 1223 return "ESS1868" ; 1224 } 1225 return NULL ; 1226} 1227 1228static void 1229ess1868_attach(u_long csn, u_long vend_id, char *name, 1230 struct isa_device *dev) 1231{ 1232 struct pnp_cinfo d ; 1233 snddev_info tmp_d ; /* patched copy of the basic snddev_info */ 1234 1235 tmp_d = sb_op_desc; 1236 snddev_last_probed = &tmp_d; 1237 1238#if 0 1239 read_pnp_parms ( &d , 3 ); /* disable LDN 3 */ 1240 d.port[0] = 0 ; 1241 d.enable = 0 ; 1242 write_pnp_parms ( &d , 3 ); 1243 1244 read_pnp_parms ( &d , 2 ); /* disable LDN 2 */ 1245 d.port[0] = 0 ; 1246 d.enable = 0 ; 1247 write_pnp_parms ( &d , 2 ); 1248 read_pnp_parms ( &d , 0 ); /* read config base */ 1249 tmp_d.conf_base = d.port[0]; 1250 write_pnp_parms ( &d , 0 ); 1251#endif 1252 1253 read_pnp_parms ( &d , 1 ) ; 1254 dev->id_iobase = d.port[0]; 1255 d.port[1] = 0 ; 1256 d.port[2] = 0 ; 1257 write_pnp_parms ( &d , 1 ); 1258 enable_pnp_card(); 1259 1260 dev->id_drq = d.drq[0] ; /* primary dma */ 1261 dev->id_irq = (1 << d.irq[0] ) ; 1262 dev->id_intr = (inthand2_t *)pcmintr ; 1263 dev->id_flags = 0 /* DV_F_DUAL_DMA | (d.drq[1] ) */; 1264 1265#if 0 1266 snddev_last_probed->probe(dev); /* not really necessary but doesn't harm */ 1267#endif 1268 pcmattach(dev); 1269} 1270 1271/* 1272 * A driver for some SB16pnp and compatibles... 1273 * 1274 * Avance Asound 100 -- 0x01009305 1275 * Avance Logic ALS100+ -- 0x10019305 1276 * Avance Logic ASound Gold ALS120 -- 0x20019305 1277 * xxx -- 0x2b008c0e 1278 * 1279 */ 1280 1281static char *sb16pnp_probe(u_long csn, u_long vend_id); 1282static void sb16pnp_attach(u_long csn, u_long vend_id, char *name, 1283 struct isa_device *dev); 1284 1285static struct pnp_device sb16pnp = { 1286 "SB16pnp", 1287 sb16pnp_probe, 1288 sb16pnp_attach, 1289 &nsnd, /* use this for all sound cards */ 1290 &tty_imask /* imask */ 1291}; 1292DATA_SET (pnpdevice_set, sb16pnp); 1293 1294static char * 1295sb16pnp_probe(u_long csn, u_long vend_id) 1296{ 1297 char *s = NULL ; 1298 1299 /* 1300 * The SB16/AWExx cards seem to differ in the fourth byte of 1301 * the vendor id, so I have just masked it for the time being... 1302 * Reported values are: 1303 * SB16 Value PnP: 0x2b008c0e 1304 * SB AWExx PnP: 0x39008c0e 0x9d008c0e 0xc3008c0e 1305 * Vibra16X: 0xf0008c0e 1306 */ 1307 if (vend_id == 0xf0008c0e) 1308 s = "Vibra16X" ; 1309 else if ( (vend_id & 0xffffff) == (0x9d008c0e & 0xffffff) ) 1310 s = "SB16 PnP"; 1311 else if (vend_id == 0x01009305) 1312 s = "Avance Asound 100" ; 1313 else if (vend_id == 0x10019305) 1314 s = "Avance Logic 100+" ; /* Vibra16X-class */ 1315 else if (vend_id == 0x20019305) 1316 s = "Avance Logic ALS120" ; /* Vibra16X-class */ 1317 if (s) { 1318 struct pnp_cinfo d; 1319 read_pnp_parms(&d, 0); 1320 if (d.enable == 0) { 1321 printf("This is a %s, but LDN 0 is disabled\n", s); 1322 return NULL ; 1323 } 1324 return s ; 1325 } 1326 return NULL ; 1327} 1328 1329static void 1330sb16pnp_attach(u_long csn, u_long vend_id, char *name, 1331 struct isa_device *dev) 1332{ 1333 struct pnp_cinfo d ; 1334 snddev_info tmp_d ; /* patched copy of the basic snddev_info */ 1335 1336 tmp_d = sb_op_desc; 1337 snddev_last_probed = &tmp_d; 1338 1339 read_pnp_parms ( &d , 0 ) ; 1340 d.port[1] = 0 ; /* only the first address is used */ 1341 dev->id_iobase = d.port[0]; 1342 tmp_d.synth_base = d.port[2]; 1343 write_pnp_parms ( &d , 0 ); 1344 enable_pnp_card(); 1345 1346 dev->id_drq = d.drq[0] ; /* primary dma */ 1347 dev->id_irq = (1 << d.irq[0] ) ; 1348 dev->id_intr = (inthand2_t *)pcmintr ; 1349 dev->id_flags = DV_F_DUAL_DMA | (d.drq[1] ) ; 1350 1351 pcm_info[dev->id_unit] = tmp_d; /* pcm_info[] will be reinitialized after */ 1352 snddev_last_probed->probe(dev); /* not really necessary but doesn't harm */ 1353 1354 if (vend_id == 0x10019305 || vend_id == 0xf0008c0e 1355 || vend_id == 0x20019305) { 1356 /* 1357 * XXX please add here the vend_id for other vibra16X cards... 1358 * And remember, must change tmp_d, not 1359 */ 1360 tmp_d.bd_flags |= BD_F_SB16X ; 1361 } 1362 pcmattach(dev); 1363} 1364#endif /* NPNP */ 1365 1366#endif 1367