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