sb16.c (54237) | sb16.c (54462) |
---|---|
1/* 2 * Copyright (c) 1999 Cameron Grant <gandalf@vilnya.demon.co.uk> 3 * Copyright 1997,1998 Luigi Rizzo. 4 * 5 * Derived from files in the Voxware 3.5 distribution, 6 * Copyright by Hannu Savolainen 1994, under the same copyright 7 * conditions. 8 * All rights reserved. --- 14 unchanged lines hidden (view full) --- 23 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 24 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 25 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 26 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 27 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 28 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 29 * SUCH DAMAGE. 30 * | 1/* 2 * Copyright (c) 1999 Cameron Grant <gandalf@vilnya.demon.co.uk> 3 * Copyright 1997,1998 Luigi Rizzo. 4 * 5 * Derived from files in the Voxware 3.5 distribution, 6 * Copyright by Hannu Savolainen 1994, under the same copyright 7 * conditions. 8 * All rights reserved. --- 14 unchanged lines hidden (view full) --- 23 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 24 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 25 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 26 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 27 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 28 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 29 * SUCH DAMAGE. 30 * |
31 * $FreeBSD: head/sys/dev/sound/isa/sb16.c 54237 1999-12-07 01:53:24Z billf $ | 31 * $FreeBSD: head/sys/dev/sound/isa/sb16.c 54462 1999-12-12 02:30:19Z cg $ |
32 */ 33 34#include <dev/sound/pcm/sound.h> 35 36#include "sbc.h" 37 38#define __SB_MIXER_C__ /* XXX warning... */ 39#include <dev/sound/isa/sb.h> --- 15 unchanged lines hidden (view full) --- 55#endif 56static int esschan_setdir(void *data, int dir); 57static int esschan_setformat(void *data, u_int32_t format); 58static int esschan_setspeed(void *data, u_int32_t speed); 59static int esschan_setblocksize(void *data, u_int32_t blocksize); 60static int esschan_trigger(void *data, int go); 61static int esschan_getptr(void *data); 62static pcmchan_caps *esschan_getcaps(void *data); | 32 */ 33 34#include <dev/sound/pcm/sound.h> 35 36#include "sbc.h" 37 38#define __SB_MIXER_C__ /* XXX warning... */ 39#include <dev/sound/isa/sb.h> --- 15 unchanged lines hidden (view full) --- 55#endif 56static int esschan_setdir(void *data, int dir); 57static int esschan_setformat(void *data, u_int32_t format); 58static int esschan_setspeed(void *data, u_int32_t speed); 59static int esschan_setblocksize(void *data, u_int32_t blocksize); 60static int esschan_trigger(void *data, int go); 61static int esschan_getptr(void *data); 62static pcmchan_caps *esschan_getcaps(void *data); |
63 |
|
63static pcmchan_caps sb_playcaps = { 64 4000, 22050, 65 AFMT_U8, 66 AFMT_U8 67}; 68 69static pcmchan_caps sb_reccaps = { 70 4000, 13000, --- 8 unchanged lines hidden (view full) --- 79}; 80 81static pcmchan_caps sbpro_reccaps = { 82 4000, 15000, 83 AFMT_STEREO | AFMT_U8, 84 AFMT_STEREO | AFMT_U8 85}; 86 | 64static pcmchan_caps sb_playcaps = { 65 4000, 22050, 66 AFMT_U8, 67 AFMT_U8 68}; 69 70static pcmchan_caps sb_reccaps = { 71 4000, 13000, --- 8 unchanged lines hidden (view full) --- 80}; 81 82static pcmchan_caps sbpro_reccaps = { 83 4000, 15000, 84 AFMT_STEREO | AFMT_U8, 85 AFMT_STEREO | AFMT_U8 86}; 87 |
87static pcmchan_caps sb16_playcaps = { | 88static pcmchan_caps sb16_hcaps = { |
88 5000, 45000, 89 AFMT_STEREO | AFMT_S16_LE, 90 AFMT_STEREO | AFMT_S16_LE 91}; 92 | 89 5000, 45000, 90 AFMT_STEREO | AFMT_S16_LE, 91 AFMT_STEREO | AFMT_S16_LE 92}; 93 |
93static pcmchan_caps sb16_reccaps = { | 94static pcmchan_caps sb16_lcaps = { |
94 5000, 45000, 95 AFMT_STEREO | AFMT_U8, 96 AFMT_STEREO | AFMT_U8 97}; 98 | 95 5000, 45000, 96 AFMT_STEREO | AFMT_U8, 97 AFMT_STEREO | AFMT_U8 98}; 99 |
100static pcmchan_caps sb16x_caps = { 101 5000, 49000, 102 AFMT_STEREO | AFMT_U8 /* | AFMT_S16_LE */, 103 AFMT_STEREO | AFMT_U8 /* AFMT_S16_LE */ 104}; 105 |
|
99static pcmchan_caps ess_playcaps = { 100 5000, 49000, 101 AFMT_STEREO | AFMT_U8 | AFMT_S16_LE, 102 AFMT_STEREO | AFMT_S16_LE 103}; 104 105static pcmchan_caps ess_reccaps = { 106 5000, 49000, --- 32 unchanged lines hidden (view full) --- 139 snd_dbuf *buffer; 140 int dir; 141 u_int32_t fmt; 142 int ess_dma_started; 143}; 144 145struct sb_info { 146 struct resource *io_base; /* I/O address for the board */ | 106static pcmchan_caps ess_playcaps = { 107 5000, 49000, 108 AFMT_STEREO | AFMT_U8 | AFMT_S16_LE, 109 AFMT_STEREO | AFMT_S16_LE 110}; 111 112static pcmchan_caps ess_reccaps = { 113 5000, 49000, --- 32 unchanged lines hidden (view full) --- 146 snd_dbuf *buffer; 147 int dir; 148 u_int32_t fmt; 149 int ess_dma_started; 150}; 151 152struct sb_info { 153 struct resource *io_base; /* I/O address for the board */ |
147 int io_rid; | |
148 struct resource *irq; | 154 struct resource *irq; |
149 int irq_rid; 150 struct resource *drq1; /* play */ 151 int drq1_rid; 152 struct resource *drq2; /* rec */ 153 int drq2_rid; | 155 struct resource *drq1; 156 struct resource *drq2; |
154 bus_dma_tag_t parent_dmat; 155 | 157 bus_dma_tag_t parent_dmat; 158 |
156 int dma16, dma8; | |
157 int bd_id; 158 u_long bd_flags; /* board-specific flags */ 159 struct sb_chinfo pch, rch; 160}; 161 162static int sb_rd(struct sb_info *sb, int reg); 163static void sb_wr(struct sb_info *sb, int reg, u_int8_t val); 164static int sb_dspready(struct sb_info *sb); 165static int sb_cmd(struct sb_info *sb, u_char val); 166static int sb_cmd1(struct sb_info *sb, u_char cmd, int val); 167static int sb_cmd2(struct sb_info *sb, u_char cmd, int val); 168static u_int sb_get_byte(struct sb_info *sb); | 159 int bd_id; 160 u_long bd_flags; /* board-specific flags */ 161 struct sb_chinfo pch, rch; 162}; 163 164static int sb_rd(struct sb_info *sb, int reg); 165static void sb_wr(struct sb_info *sb, int reg, u_int8_t val); 166static int sb_dspready(struct sb_info *sb); 167static int sb_cmd(struct sb_info *sb, u_char val); 168static int sb_cmd1(struct sb_info *sb, u_char cmd, int val); 169static int sb_cmd2(struct sb_info *sb, u_char cmd, int val); 170static u_int sb_get_byte(struct sb_info *sb); |
169static int ess_write(struct sb_info *sb, u_char reg, int val); 170static int ess_read(struct sb_info *sb, u_char reg); 171 172/* 173 * in the SB, there is a set of indirect "mixer" registers with 174 * address at offset 4, data at offset 5 175 */ | |
176static void sb_setmixer(struct sb_info *sb, u_int port, u_int value); 177static int sb_getmixer(struct sb_info *sb, u_int port); | 171static void sb_setmixer(struct sb_info *sb, u_int port, u_int value); 172static int sb_getmixer(struct sb_info *sb, u_int port); |
178 179static void sb_intr(void *arg); 180static void ess_intr(void *arg); 181static int sb_init(device_t dev, struct sb_info *sb); | |
182static int sb_reset_dsp(struct sb_info *sb); 183 | 173static int sb_reset_dsp(struct sb_info *sb); 174 |
175static void sb_intr(void *arg); |
|
184static int sb_format(struct sb_chinfo *ch, u_int32_t format); 185static int sb_speed(struct sb_chinfo *ch, int speed); 186static int sb_start(struct sb_chinfo *ch); 187static int sb_stop(struct sb_chinfo *ch); 188 | 176static int sb_format(struct sb_chinfo *ch, u_int32_t format); 177static int sb_speed(struct sb_chinfo *ch, int speed); 178static int sb_start(struct sb_chinfo *ch); 179static int sb_stop(struct sb_chinfo *ch); 180 |
181static int ess_write(struct sb_info *sb, u_char reg, int val); 182static int ess_read(struct sb_info *sb, u_char reg); 183static void ess_intr(void *arg); |
|
189static int ess_format(struct sb_chinfo *ch, u_int32_t format); 190static int ess_speed(struct sb_chinfo *ch, int speed); 191static int ess_start(struct sb_chinfo *ch); 192static int ess_stop(struct sb_chinfo *ch); 193static int ess_abort(struct sb_chinfo *ch); | 184static int ess_format(struct sb_chinfo *ch, u_int32_t format); 185static int ess_speed(struct sb_chinfo *ch, int speed); 186static int ess_start(struct sb_chinfo *ch); 187static int ess_stop(struct sb_chinfo *ch); 188static int ess_abort(struct sb_chinfo *ch); |
189 |
|
194static int sbmix_init(snd_mixer *m); 195static int sbmix_set(snd_mixer *m, unsigned dev, unsigned left, unsigned right); 196static int sbmix_setrecsrc(snd_mixer *m, u_int32_t src); 197 198static snd_mixer sb_mixer = { 199 "SoundBlaster mixer", 200 sbmix_init, 201 sbmix_set, --- 170 unchanged lines hidden (view full) --- 372 return 0; 373} 374 375static void 376sb_release_resources(struct sb_info *sb, device_t dev) 377{ 378 /* should we bus_teardown_intr here? */ 379 if (sb->irq) { | 190static int sbmix_init(snd_mixer *m); 191static int sbmix_set(snd_mixer *m, unsigned dev, unsigned left, unsigned right); 192static int sbmix_setrecsrc(snd_mixer *m, u_int32_t src); 193 194static snd_mixer sb_mixer = { 195 "SoundBlaster mixer", 196 sbmix_init, 197 sbmix_set, --- 170 unchanged lines hidden (view full) --- 368 return 0; 369} 370 371static void 372sb_release_resources(struct sb_info *sb, device_t dev) 373{ 374 /* should we bus_teardown_intr here? */ 375 if (sb->irq) { |
380 bus_release_resource(dev, SYS_RES_IRQ, sb->irq_rid, sb->irq); | 376 bus_release_resource(dev, SYS_RES_IRQ, 0, sb->irq); |
381 sb->irq = 0; 382 } 383 if (sb->drq1) { | 377 sb->irq = 0; 378 } 379 if (sb->drq1) { |
384 bus_release_resource(dev, SYS_RES_DRQ, sb->drq1_rid, sb->drq1); | 380 bus_release_resource(dev, SYS_RES_DRQ, 0, sb->drq1); |
385 sb->drq1 = 0; 386 } 387 if (sb->drq2) { | 381 sb->drq1 = 0; 382 } 383 if (sb->drq2) { |
388 bus_release_resource(dev, SYS_RES_DRQ, sb->drq2_rid, sb->drq2); | 384 bus_release_resource(dev, SYS_RES_DRQ, 1, sb->drq2); |
389 sb->drq2 = 0; 390 } 391 if (sb->io_base) { | 385 sb->drq2 = 0; 386 } 387 if (sb->io_base) { |
392 bus_release_resource(dev, SYS_RES_IOPORT, sb->io_rid, 393 sb->io_base); | 388 bus_release_resource(dev, SYS_RES_IOPORT, 0, sb->io_base); |
394 sb->io_base = 0; 395 } 396 free(sb, M_DEVBUF); 397} 398 399static int 400sb_alloc_resources(struct sb_info *sb, device_t dev) 401{ | 389 sb->io_base = 0; 390 } 391 free(sb, M_DEVBUF); 392} 393 394static int 395sb_alloc_resources(struct sb_info *sb, device_t dev) 396{ |
397 int rid; 398 399 rid = 0; |
|
402 if (!sb->io_base) 403 sb->io_base = bus_alloc_resource(dev, SYS_RES_IOPORT, | 400 if (!sb->io_base) 401 sb->io_base = bus_alloc_resource(dev, SYS_RES_IOPORT, |
404 &sb->io_rid, 0, ~0, 1, | 402 &rid, 0, ~0, 1, |
405 RF_ACTIVE); | 403 RF_ACTIVE); |
404 rid = 0; |
|
406 if (!sb->irq) 407 sb->irq = bus_alloc_resource(dev, SYS_RES_IRQ, | 405 if (!sb->irq) 406 sb->irq = bus_alloc_resource(dev, SYS_RES_IRQ, |
408 &sb->irq_rid, 0, ~0, 1, | 407 &rid, 0, ~0, 1, |
409 RF_ACTIVE); | 408 RF_ACTIVE); |
409 rid = 0; |
|
410 if (!sb->drq1) 411 sb->drq1 = bus_alloc_resource(dev, SYS_RES_DRQ, | 410 if (!sb->drq1) 411 sb->drq1 = bus_alloc_resource(dev, SYS_RES_DRQ, |
412 &sb->drq1_rid, 0, ~0, 1, | 412 &rid, 0, ~0, 1, |
413 RF_ACTIVE); | 413 RF_ACTIVE); |
414 if (!sb->drq2 && sb->drq2_rid > 0) | 414 rid = 1; 415 if (!sb->drq2) |
415 sb->drq2 = bus_alloc_resource(dev, SYS_RES_DRQ, | 416 sb->drq2 = bus_alloc_resource(dev, SYS_RES_DRQ, |
416 &sb->drq2_rid, 0, ~0, 1, | 417 &rid, 0, ~0, 1, |
417 RF_ACTIVE); 418 419 if (sb->io_base && sb->drq1 && sb->irq) { | 418 RF_ACTIVE); 419 420 if (sb->io_base && sb->drq1 && sb->irq) { |
420 sb->dma8 = rman_get_start(sb->drq1); 421 isa_dma_acquire(sb->dma8); 422 isa_dmainit(sb->dma8, DSP_BUFFSIZE); | 421 isa_dma_acquire(rman_get_start(sb->drq1)); 422 isa_dmainit(rman_get_start(sb->drq1), DSP_BUFFSIZE); |
423 424 if (sb->drq2) { | 423 424 if (sb->drq2) { |
425 sb->dma16 = rman_get_start(sb->drq2); 426 isa_dma_acquire(sb->dma16); 427 isa_dmainit(sb->dma16, DSP_BUFFSIZE); 428 } else sb->dma16 = sb->dma8; 429 430 if (sb->dma8 > sb->dma16) { 431 int tmp = sb->dma16; 432 sb->dma16 = sb->dma8; 433 sb->dma8 = tmp; | 425 isa_dma_acquire(rman_get_start(sb->drq2)); 426 isa_dmainit(rman_get_start(sb->drq2), DSP_BUFFSIZE); |
434 } | 427 } |
428 |
|
435 return 0; 436 } else return ENXIO; 437} 438 | 429 return 0; 430 } else return ENXIO; 431} 432 |
439static int 440sb_identify_board(device_t dev, struct sb_info *sb) | 433static void 434sb16_swap(void *v, int dir) |
441{ | 435{ |
442 char *fmt = NULL; 443 static char buf[64]; 444 int essver = 0; | 436 struct sb_info *sb = v; 437 int pb = sb->pch.buffer->dl; 438 int rb = sb->rch.buffer->dl; 439 int pc = sb->pch.buffer->chan; 440 int rc = sb->rch.buffer->chan; 441 int swp = 0; |
445 | 442 |
446 sb_cmd(sb, DSP_CMD_GETVER); /* Get version */ 447 sb->bd_id = (sb_get_byte(sb) << 8) | sb_get_byte(sb); | 443 if (!pb && !rb) { 444 if (dir == PCMDIR_PLAY && pc < 4) swp = 1; 445 else if (dir == PCMDIR_REC && rc < 4) swp = 1; 446 if (sb->bd_flags & BD_F_SB16X) swp = !swp; 447 if (swp) { 448 int t; |
448 | 449 |
449 switch (sb->bd_id >> 8) { 450 case 1: /* old sound blaster has nothing... */ 451 case 2: 452 fmt = "SoundBlaster %d.%d" ; /* default */ 453 break; 454 455 case 3: 456 fmt = "SoundBlaster Pro %d.%d"; 457 if (sb->bd_id == 0x301) { 458 int rev; 459 460 /* Try to detect ESS chips. */ 461 sb_cmd(sb, DSP_CMD_GETID); /* Return ident. bytes. */ 462 essver = (sb_get_byte(sb) << 8) | sb_get_byte(sb); 463 rev = essver & 0x000f; 464 essver &= 0xfff0; 465 if (essver == 0x4880) { 466 /* the ESS488 can be treated as an SBPRO */ 467 fmt = "SoundBlaster Pro (ESS488 rev %d)"; 468 } else if (essver == 0x6880) { 469 if (rev < 8) fmt = "ESS688 rev %d"; 470 else fmt = "ESS1868 rev %d"; 471 sb->bd_flags |= BD_F_ESS; 472 } else return ENXIO; 473 sb->bd_id &= 0xff00; 474 sb->bd_id |= ((essver & 0xf000) >> 8) | rev; | 450 t = sb->pch.buffer->chan; 451 sb->pch.buffer->chan = sb->rch.buffer->chan; 452 sb->rch.buffer->chan = t; 453 sb->pch.buffer->dir = B_WRITE; 454 sb->rch.buffer->dir = B_READ; |
475 } | 455 } |
476 break; 477 478 case 4: 479 sb->bd_flags |= BD_F_SB16; 480 if (sb->bd_flags & BD_F_SB16X) fmt = "SB16 ViBRA16X %d.%d"; 481 else fmt = "SoundBlaster 16 %d.%d"; 482 break; 483 484 default: 485 device_printf(dev, "failed to get SB version (%x)\n", 486 sb->bd_id); 487 return ENXIO; 488 } 489 if (essver) snprintf(buf, sizeof buf, fmt, sb->bd_id & 0x000f); 490 else snprintf(buf, sizeof buf, fmt, sb->bd_id >> 8, sb->bd_id & 0xff); 491 device_set_desc_copy(dev, buf); 492 return sb_reset_dsp(sb); | 456 } |
493} 494 495static int | 457} 458 459static int |
496sb_init(device_t dev, struct sb_info *sb) 497{ 498 int x, irq; 499 500 sb->bd_flags &= ~BD_F_MIX_MASK; 501 /* do various initializations depending on board id. */ 502 switch (sb->bd_id >> 8) { 503 case 1: /* old sound blaster has nothing... */ 504 break; 505 506 case 2: 507 sb->bd_flags |= BD_F_DUP_MIDI; 508 if (sb->bd_id > 0x200) sb->bd_flags |= BD_F_MIX_CT1335; 509 break; 510 511 case 3: 512 sb->bd_flags |= BD_F_DUP_MIDI | BD_F_MIX_CT1345; 513 break; 514 515 case 4: 516 sb->bd_flags |= BD_F_SB16 | BD_F_MIX_CT1745; 517 if (sb->dma16 != sb->dma8) sb->bd_flags |= BD_F_DUPLEX; 518 519 /* soft irq/dma configuration */ 520 x = -1; 521 irq = rman_get_start(sb->irq); 522 if (irq == 5) x = 2; 523 else if (irq == 7) x = 4; 524 else if (irq == 9) x = 1; 525 else if (irq == 10) x = 8; 526 if (x == -1) device_printf(dev, 527 "bad irq %d (5/7/9/10 valid)\n", 528 irq); 529 else sb_setmixer(sb, IRQ_NR, x); 530 sb_setmixer(sb, DMA_NR, (1 << sb->dma16) | (1 << sb->dma8)); 531 break; 532 } 533 return 0; 534} 535 536static int 537sb_probe(device_t dev) 538{ 539 snddev_info *d = device_get_softc(dev); 540 struct sb_info *sb; 541 int allocated, i; 542 int error; 543 544 if (isa_get_vendorid(dev)) return ENXIO; /* not yet */ 545 546 device_set_desc(dev, "SoundBlaster"); 547 bzero(d, sizeof *d); 548 sb = (struct sb_info *)malloc(sizeof *sb, M_DEVBUF, M_NOWAIT); 549 if (!sb) return ENXIO; 550 bzero(sb, sizeof *sb); 551 552 allocated = 0; 553 sb->io_rid = 0; 554 sb->io_base = bus_alloc_resource(dev, SYS_RES_IOPORT, &sb->io_rid, 555 0, ~0, 16, RF_ACTIVE); 556 if (!sb->io_base) { 557 BVDDB(printf("sb_probe: no addr, trying (0x220, 0x240)\n")); 558 allocated = 1; 559 sb->io_rid = 0; 560 sb->io_base = bus_alloc_resource(dev, SYS_RES_IOPORT, 561 &sb->io_rid, 0x220, 0x22f, 562 16, RF_ACTIVE); 563 if (!sb->io_base) { 564 sb->io_base = bus_alloc_resource(dev, SYS_RES_IOPORT, 565 &sb->io_rid, 0x240, 566 0x24f, 16, RF_ACTIVE); 567 } 568 } 569 if (!sb->io_base) return ENXIO; 570 571 error = sb_reset_dsp(sb); 572 if (error) goto no; 573 error = sb_identify_board(dev, sb); 574 if (error) goto no; 575no: 576 i = sb->io_rid; 577 sb_release_resources(sb, dev); 578 if (allocated) bus_delete_resource(dev, SYS_RES_IOPORT, i); 579 return error; 580} 581 582static int | |
583sb_doattach(device_t dev, struct sb_info *sb) 584{ 585 snddev_info *d = device_get_softc(dev); 586 void *ih; | 460sb_doattach(device_t dev, struct sb_info *sb) 461{ 462 snddev_info *d = device_get_softc(dev); 463 void *ih; |
587 int error; | |
588 char status[SND_STATUSLEN]; 589 | 464 char status[SND_STATUSLEN]; 465 |
590 sb->irq_rid = 0; 591 sb->drq1_rid = 0; 592 sb->drq2_rid = 1; | |
593 if (sb_alloc_resources(sb, dev)) goto no; | 466 if (sb_alloc_resources(sb, dev)) goto no; |
594 error = sb_reset_dsp(sb); 595 if (error) goto no; 596 error = sb_identify_board(dev, sb); 597 if (error) goto no; 598 599 sb_init(dev, sb); | 467 if (sb_reset_dsp(sb)) goto no; |
600 mixer_init(d, &sb_mixer, sb); | 468 mixer_init(d, &sb_mixer, sb); |
469 |
|
601 if (sb->bd_flags & BD_F_ESS) 602 bus_setup_intr(dev, sb->irq, INTR_TYPE_TTY, ess_intr, sb, &ih); 603 else 604 bus_setup_intr(dev, sb->irq, INTR_TYPE_TTY, sb_intr, sb, &ih); | 470 if (sb->bd_flags & BD_F_ESS) 471 bus_setup_intr(dev, sb->irq, INTR_TYPE_TTY, ess_intr, sb, &ih); 472 else 473 bus_setup_intr(dev, sb->irq, INTR_TYPE_TTY, sb_intr, sb, &ih); |
605 606 if (sb->bd_flags & BD_F_SB16) 607 pcm_setflags(dev, pcm_getflags(dev) | SD_F_EVILSB16); 608 if (sb->dma16 == sb->dma8) | 474 if ((sb->bd_flags & BD_F_SB16) && !(sb->bd_flags & BD_F_SB16X)) 475 pcm_setswap(dev, sb16_swap); 476 if (!sb->drq2) |
609 pcm_setflags(dev, pcm_getflags(dev) | SD_F_SIMPLEX); | 477 pcm_setflags(dev, pcm_getflags(dev) | SD_F_SIMPLEX); |
478 |
|
610 if (bus_dma_tag_create(/*parent*/NULL, /*alignment*/2, /*boundary*/0, 611 /*lowaddr*/BUS_SPACE_MAXADDR_24BIT, 612 /*highaddr*/BUS_SPACE_MAXADDR, 613 /*filter*/NULL, /*filterarg*/NULL, 614 /*maxsize*/DSP_BUFFSIZE, /*nsegments*/1, 615 /*maxsegz*/0x3ffff, 616 /*flags*/0, &sb->parent_dmat) != 0) { 617 device_printf(dev, "unable to create dma tag\n"); 618 goto no; 619 } 620 | 479 if (bus_dma_tag_create(/*parent*/NULL, /*alignment*/2, /*boundary*/0, 480 /*lowaddr*/BUS_SPACE_MAXADDR_24BIT, 481 /*highaddr*/BUS_SPACE_MAXADDR, 482 /*filter*/NULL, /*filterarg*/NULL, 483 /*maxsize*/DSP_BUFFSIZE, /*nsegments*/1, 484 /*maxsegz*/0x3ffff, 485 /*flags*/0, &sb->parent_dmat) != 0) { 486 device_printf(dev, "unable to create dma tag\n"); 487 goto no; 488 } 489 |
621 snprintf(status, SND_STATUSLEN, "at io 0x%lx irq %ld drq %d", | 490 snprintf(status, SND_STATUSLEN, "at io 0x%lx irq %ld drq %ld", |
622 rman_get_start(sb->io_base), rman_get_start(sb->irq), | 491 rman_get_start(sb->io_base), rman_get_start(sb->irq), |
623 sb->dma8); 624 if (sb->dma16 != sb->dma8) snprintf(status + strlen(status), 625 SND_STATUSLEN - strlen(status), ":%d", sb->dma16); | 492 rman_get_start(sb->drq1)); 493 if (sb->drq2) snprintf(status + strlen(status), SND_STATUSLEN - strlen(status), 494 ":%ld", rman_get_start(sb->drq2)); |
626 627 if (pcm_register(dev, sb, 1, 1)) goto no; 628 if (sb->bd_flags & BD_F_ESS) { 629 pcm_addchan(dev, PCMDIR_REC, &ess_chantemplate, sb); 630 pcm_addchan(dev, PCMDIR_PLAY, &ess_chantemplate, sb); 631 } else { 632 pcm_addchan(dev, PCMDIR_REC, &sb_chantemplate, sb); 633 pcm_addchan(dev, PCMDIR_PLAY, &sb_chantemplate, sb); 634 } 635 pcm_setstatus(dev, status); 636 637 return 0; 638 639no: 640 sb_release_resources(sb, dev); 641 return ENXIO; 642} 643 | 495 496 if (pcm_register(dev, sb, 1, 1)) goto no; 497 if (sb->bd_flags & BD_F_ESS) { 498 pcm_addchan(dev, PCMDIR_REC, &ess_chantemplate, sb); 499 pcm_addchan(dev, PCMDIR_PLAY, &ess_chantemplate, sb); 500 } else { 501 pcm_addchan(dev, PCMDIR_REC, &sb_chantemplate, sb); 502 pcm_addchan(dev, PCMDIR_PLAY, &sb_chantemplate, sb); 503 } 504 pcm_setstatus(dev, status); 505 506 return 0; 507 508no: 509 sb_release_resources(sb, dev); 510 return ENXIO; 511} 512 |
644static int 645sb_attach(device_t dev) 646{ 647 struct sb_info *sb; 648 int flags = device_get_flags(dev); 649 650 if (flags & DV_F_DUAL_DMA) { 651 bus_set_resource(dev, SYS_RES_DRQ, 1, 652 flags & DV_F_DRQ_MASK, 1); 653 } 654 sb = (struct sb_info *)malloc(sizeof *sb, M_DEVBUF, M_NOWAIT); 655 if (!sb) return ENXIO; 656 bzero(sb, sizeof *sb); 657 658 /* XXX in probe should set io resource to right val instead of this */ 659 sb->io_rid = 0; 660 sb->io_base = bus_alloc_resource(dev, SYS_RES_IOPORT, &sb->io_rid, 661 0, ~0, 16, RF_ACTIVE); 662 if (!sb->io_base) { 663 BVDDB(printf("sb_probe: no addr, trying (0x220, 0x240)\n")); 664 sb->io_rid = 0; 665 sb->io_base = bus_alloc_resource(dev, SYS_RES_IOPORT, 666 &sb->io_rid, 0x220, 0x22f, 667 16, RF_ACTIVE); 668 if (!sb->io_base) { 669 sb->io_base = bus_alloc_resource(dev, SYS_RES_IOPORT, 670 &sb->io_rid, 0x240, 671 0x24f, 16, RF_ACTIVE); 672 } 673 } 674 if (!sb->io_base) return ENXIO; 675 676 return sb_doattach(dev, sb); 677} 678 679static device_method_t sb_methods[] = { 680 /* Device interface */ 681 DEVMETHOD(device_probe, sb_probe), 682 DEVMETHOD(device_attach, sb_attach), 683 684 { 0, 0 } 685}; 686 687static driver_t sb_driver = { 688 "pcm", 689 sb_methods, 690 sizeof(snddev_info), 691}; 692 693DRIVER_MODULE(sb, isa, sb_driver, pcm_devclass, 0, 0); 694 | |
695static void 696sb_intr(void *arg) 697{ 698 struct sb_info *sb = (struct sb_info *)arg; 699 int reason = 3, c; 700 701 /* 702 * SB < 4.0 is half duplex and has only 1 bit for int source, --- 121 unchanged lines hidden (view full) --- 824static int 825sb_start(struct sb_chinfo *ch) 826{ 827 struct sb_info *sb = ch->parent; 828 int play = (ch->dir == PCMDIR_PLAY)? 1 : 0; 829 int b16 = (ch->fmt & AFMT_S16_LE)? 1 : 0; 830 int stereo = (ch->fmt & AFMT_STEREO)? 1 : 0; 831 int l = ch->buffer->dl; | 513static void 514sb_intr(void *arg) 515{ 516 struct sb_info *sb = (struct sb_info *)arg; 517 int reason = 3, c; 518 519 /* 520 * SB < 4.0 is half duplex and has only 1 bit for int source, --- 121 unchanged lines hidden (view full) --- 642static int 643sb_start(struct sb_chinfo *ch) 644{ 645 struct sb_info *sb = ch->parent; 646 int play = (ch->dir == PCMDIR_PLAY)? 1 : 0; 647 int b16 = (ch->fmt & AFMT_S16_LE)? 1 : 0; 648 int stereo = (ch->fmt & AFMT_STEREO)? 1 : 0; 649 int l = ch->buffer->dl; |
650 int dh = ch->buffer->chan > 3; |
|
832 u_char i1, i2 = 0; 833 834 if (b16) l >>= 1; 835 l--; 836 if (play) sb_cmd(sb, DSP_CMD_SPKON); 837 if (sb->bd_flags & BD_F_SB16) { 838 i1 = DSP_F16_AUTO | DSP_F16_FIFO_ON | 839 (play? DSP_F16_DAC : DSP_F16_ADC); | 651 u_char i1, i2 = 0; 652 653 if (b16) l >>= 1; 654 l--; 655 if (play) sb_cmd(sb, DSP_CMD_SPKON); 656 if (sb->bd_flags & BD_F_SB16) { 657 i1 = DSP_F16_AUTO | DSP_F16_FIFO_ON | 658 (play? DSP_F16_DAC : DSP_F16_ADC); |
840 i1 |= (b16 && (sb->bd_flags & BD_F_DUPLEX))? DSP_DMA16 : DSP_DMA8; | 659 i1 |= (b16 || dh)? DSP_DMA16 : DSP_DMA8; |
841 i2 = (stereo? DSP_F16_STEREO : 0) | (b16? DSP_F16_SIGNED : 0); 842 sb_cmd(sb, i1); 843 sb_cmd2(sb, i2, l); 844 } else { 845 if (sb->bd_flags & BD_F_HISPEED) i1 = play? 0x90 : 0x98; 846 else i1 = play? 0x1c : 0x2c; 847 sb_setmixer(sb, 0x0e, stereo? 2 : 0); 848 /* an ESS extension -- they can do 16 bits */ --- 145 unchanged lines hidden (view full) --- 994 struct sb_info *sb = devinfo; 995 struct sb_chinfo *ch = (dir == PCMDIR_PLAY)? &sb->pch : &sb->rch; 996 997 ch->parent = sb; 998 ch->channel = c; 999 ch->buffer = b; 1000 ch->buffer->bufsize = DSP_BUFFSIZE; 1001 if (chn_allocbuf(ch->buffer, sb->parent_dmat) == -1) return NULL; | 660 i2 = (stereo? DSP_F16_STEREO : 0) | (b16? DSP_F16_SIGNED : 0); 661 sb_cmd(sb, i1); 662 sb_cmd2(sb, i2, l); 663 } else { 664 if (sb->bd_flags & BD_F_HISPEED) i1 = play? 0x90 : 0x98; 665 else i1 = play? 0x1c : 0x2c; 666 sb_setmixer(sb, 0x0e, stereo? 2 : 0); 667 /* an ESS extension -- they can do 16 bits */ --- 145 unchanged lines hidden (view full) --- 813 struct sb_info *sb = devinfo; 814 struct sb_chinfo *ch = (dir == PCMDIR_PLAY)? &sb->pch : &sb->rch; 815 816 ch->parent = sb; 817 ch->channel = c; 818 ch->buffer = b; 819 ch->buffer->bufsize = DSP_BUFFSIZE; 820 if (chn_allocbuf(ch->buffer, sb->parent_dmat) == -1) return NULL; |
1002 ch->buffer->chan = (dir == PCMDIR_PLAY)? sb->dma16 : sb->dma8; | 821 ch->buffer->chan = (dir == PCMDIR_PLAY)? rman_get_start(sb->drq2) 822 : rman_get_start(sb->drq1); |
1003 return ch; 1004} 1005 1006static int 1007sbchan_setdir(void *data, int dir) 1008{ 1009 struct sb_chinfo *ch = data; 1010 ch->dir = dir; --- 37 unchanged lines hidden (view full) --- 1048 return buf_isadmaptr(ch->buffer); 1049} 1050 1051static pcmchan_caps * 1052sbchan_getcaps(void *data) 1053{ 1054 struct sb_chinfo *ch = data; 1055 int p = (ch->dir == PCMDIR_PLAY)? 1 : 0; | 823 return ch; 824} 825 826static int 827sbchan_setdir(void *data, int dir) 828{ 829 struct sb_chinfo *ch = data; 830 ch->dir = dir; --- 37 unchanged lines hidden (view full) --- 868 return buf_isadmaptr(ch->buffer); 869} 870 871static pcmchan_caps * 872sbchan_getcaps(void *data) 873{ 874 struct sb_chinfo *ch = data; 875 int p = (ch->dir == PCMDIR_PLAY)? 1 : 0; |
1056 if (ch->parent->bd_id <= 0x200) | 876 if (ch->parent->bd_id < 0x300) |
1057 return p? &sb_playcaps : &sb_reccaps; | 877 return p? &sb_playcaps : &sb_reccaps; |
1058 else if (ch->parent->bd_id >= 0x400) 1059 return p? &sb16_playcaps : &sb16_reccaps; 1060 else | 878 else if (ch->parent->bd_id < 0x400) |
1061 return p? &sbpro_playcaps : &sbpro_reccaps; | 879 return p? &sbpro_playcaps : &sbpro_reccaps; |
880 else if (ch->parent->bd_flags & BD_F_SB16X) 881 return &sb16x_caps; 882 else 883 return (ch->buffer->chan >= 4)? &sb16_hcaps : &sb16_lcaps; |
|
1062} 1063/* channel interface for ESS18xx */ 1064#ifdef notyet 1065static void * 1066esschan_init(void *devinfo, snd_dbuf *b, pcm_channel *c, int dir) 1067{ 1068 /* the same as sbchan_init()? */ 1069} --- 178 unchanged lines hidden (view full) --- 1248 */ 1249 sb_setmixer(sb, SB16_OMASK, 0x1f & ~1); 1250 break; 1251 } 1252 return src; 1253} 1254 1255static int | 884} 885/* channel interface for ESS18xx */ 886#ifdef notyet 887static void * 888esschan_init(void *devinfo, snd_dbuf *b, pcm_channel *c, int dir) 889{ 890 /* the same as sbchan_init()? */ 891} --- 178 unchanged lines hidden (view full) --- 1070 */ 1071 sb_setmixer(sb, SB16_OMASK, 0x1f & ~1); 1072 break; 1073 } 1074 return src; 1075} 1076 1077static int |
1256sbpnp_probe(device_t dev) 1257{ 1258 char *s = NULL; 1259 u_int32_t logical_id = isa_get_logicalid(dev); 1260 1261 switch(logical_id) { 1262 case 0x01000000: /* @@@0001 */ 1263 s = "Avance Asound 100"; 1264 break; 1265 1266 case 0x01100000: /* @@@1001 */ 1267 s = "Avance Asound 110"; 1268 break; 1269 1270 case 0x01200000: /* @@@2001 */ 1271 s = "Avance Logic ALS120"; 1272 break; 1273 1274 case 0x68187316: /* ESS1868 */ 1275 s = "ESS1868"; 1276 break; 1277 1278 case 0x69187316: /* ESS1869 */ 1279 case 0xacb0110e: /* Compaq's Presario 1621 ESS1869 */ 1280 s = "ESS1869"; 1281 break; 1282 1283 case 0x79187316: /* ESS1879 */ 1284 s = "ESS1879"; 1285 break; 1286 1287 case 0x88187316: /* ESS1888 */ 1288 s = "ESS1888"; 1289 break; 1290 } 1291 if (s) { 1292 device_set_desc(dev, s); 1293 return (0); 1294 } 1295 return ENXIO; 1296} 1297 1298static int 1299sbpnp_attach(device_t dev) 1300{ 1301 struct sb_info *sb; 1302 u_int32_t vend_id = isa_get_vendorid(dev); 1303 1304 sb = (struct sb_info *)malloc(sizeof *sb, M_DEVBUF, M_NOWAIT); 1305 if (!sb) return ENXIO; 1306 bzero(sb, sizeof *sb); 1307 1308 switch(vend_id) { 1309 case 0xf0008c0e: 1310 case 0x10019305: 1311 case 0x20019305: 1312 /* XXX add here the vend_id for other vibra16X cards... */ 1313 sb->bd_flags = BD_F_SB16X; 1314 } 1315 return sb_doattach(dev, sb); 1316} 1317 1318static device_method_t sbpnp_methods[] = { 1319 /* Device interface */ 1320 DEVMETHOD(device_probe, sbpnp_probe), 1321 DEVMETHOD(device_attach, sbpnp_attach), 1322 1323 { 0, 0 } 1324}; 1325 1326static driver_t sbpnp_driver = { 1327 "pcm", 1328 sbpnp_methods, 1329 sizeof(snddev_info), 1330}; 1331 1332DRIVER_MODULE(sbpnp, isa, sbpnp_driver, pcm_devclass, 0, 0); 1333 1334#if NSBC > 0 1335#define DESCSTR " PCM Audio" 1336static int | |
1337sbsbc_probe(device_t dev) 1338{ | 1078sbsbc_probe(device_t dev) 1079{ |
1339 char *s = NULL; 1340 struct sndcard_func *func; | 1080 char buf[64]; 1081 u_int32_t func, ver, r; |
1341 1342 /* The parent device has already been probed. */ | 1082 1083 /* The parent device has already been probed. */ |
1343 1344 func = device_get_ivars(dev); 1345 if (func == NULL || func->func != SCF_PCM) | 1084 r = BUS_READ_IVAR(device_get_parent(dev), dev, 0, &func); 1085 if (func != SCF_PCM) |
1346 return (ENXIO); 1347 | 1086 return (ENXIO); 1087 |
1348 s = "SB PCM Audio"; | 1088 r = BUS_READ_IVAR(device_get_parent(dev), dev, 1, &ver); 1089 ver &= 0x0000ffff; 1090 snprintf(buf, sizeof buf, "SB DSP %d.%02d", ver >> 8, ver & 0xff); 1091 device_set_desc_copy(dev, buf); |
1349 | 1092 |
1350 device_set_desc(dev, s); | |
1351 return 0; 1352} 1353 1354static int 1355sbsbc_attach(device_t dev) 1356{ 1357 struct sb_info *sb; | 1093 return 0; 1094} 1095 1096static int 1097sbsbc_attach(device_t dev) 1098{ 1099 struct sb_info *sb; |
1358 u_int32_t vend_id; 1359 device_t sbc; | 1100 u_int32_t ver; |
1360 | 1101 |
1361 sbc = device_get_parent(dev); 1362 vend_id = isa_get_vendorid(sbc); | |
1363 sb = (struct sb_info *)malloc(sizeof *sb, M_DEVBUF, M_NOWAIT); 1364 if (!sb) return ENXIO; 1365 bzero(sb, sizeof *sb); 1366 | 1102 sb = (struct sb_info *)malloc(sizeof *sb, M_DEVBUF, M_NOWAIT); 1103 if (!sb) return ENXIO; 1104 bzero(sb, sizeof *sb); 1105 |
1367 switch(vend_id) { 1368 case 0xf0008c0e: 1369 case 0x10019305: 1370 case 0x20019305: 1371 /* XXX add here the vend_id for other vibra16X cards... */ 1372 sb->bd_flags = BD_F_SB16X; 1373 } | 1106 BUS_READ_IVAR(device_get_parent(dev), dev, 1, &ver); 1107 sb->bd_id = ver & 0x0000ffff; 1108 sb->bd_flags = (ver & 0xffff0000) >> 16; 1109 |
1374 return sb_doattach(dev, sb); 1375} 1376 1377static device_method_t sbsbc_methods[] = { 1378 /* Device interface */ 1379 DEVMETHOD(device_probe, sbsbc_probe), 1380 DEVMETHOD(device_attach, sbsbc_attach), 1381 1382 { 0, 0 } 1383}; 1384 1385static driver_t sbsbc_driver = { 1386 "pcm", 1387 sbsbc_methods, 1388 sizeof(snddev_info), 1389}; 1390 1391DRIVER_MODULE(sbsbc, sbc, sbsbc_driver, pcm_devclass, 0, 0); 1392 | 1110 return sb_doattach(dev, sb); 1111} 1112 1113static device_method_t sbsbc_methods[] = { 1114 /* Device interface */ 1115 DEVMETHOD(device_probe, sbsbc_probe), 1116 DEVMETHOD(device_attach, sbsbc_attach), 1117 1118 { 0, 0 } 1119}; 1120 1121static driver_t sbsbc_driver = { 1122 "pcm", 1123 sbsbc_methods, 1124 sizeof(snddev_info), 1125}; 1126 1127DRIVER_MODULE(sbsbc, sbc, sbsbc_driver, pcm_devclass, 0, 0); 1128 |
1393#endif /* NSBC > 0 */ | 1129 1130 |