sb8.c (57973) | sb8.c (58756) |
---|---|
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/sb8.c 57973 2000-03-13 10:19:32Z phk $ | 31 * $FreeBSD: head/sys/dev/sound/isa/sb8.c 58756 2000-03-28 18:31:01Z 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> 40#include <dev/sound/chip.h> 41 | 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> 40#include <dev/sound/chip.h> 41 |
42#define ESS_BUFFSIZE (65536 - 256) | |
43#define PLAIN_SB16(x) ((((x)->bd_flags) & (BD_F_SB16|BD_F_SB16X)) == BD_F_SB16) 44 45/* channel interface */ 46static void *sbchan_init(void *devinfo, snd_dbuf *b, pcm_channel *c, int dir); 47static int sbchan_setdir(void *data, int dir); 48static int sbchan_setformat(void *data, u_int32_t format); 49static int sbchan_setspeed(void *data, u_int32_t speed); 50static int sbchan_setblocksize(void *data, u_int32_t blocksize); 51static int sbchan_trigger(void *data, int go); 52static int sbchan_getptr(void *data); 53static pcmchan_caps *sbchan_getcaps(void *data); 54 | 42#define PLAIN_SB16(x) ((((x)->bd_flags) & (BD_F_SB16|BD_F_SB16X)) == BD_F_SB16) 43 44/* channel interface */ 45static void *sbchan_init(void *devinfo, snd_dbuf *b, pcm_channel *c, int dir); 46static int sbchan_setdir(void *data, int dir); 47static int sbchan_setformat(void *data, u_int32_t format); 48static int sbchan_setspeed(void *data, u_int32_t speed); 49static int sbchan_setblocksize(void *data, u_int32_t blocksize); 50static int sbchan_trigger(void *data, int go); 51static int sbchan_getptr(void *data); 52static pcmchan_caps *sbchan_getcaps(void *data); 53 |
55/* channel interface for ESS */ 56static void *esschan_init(void *devinfo, snd_dbuf *b, pcm_channel *c, int dir); 57static int esschan_setdir(void *data, int dir); 58static int esschan_setformat(void *data, u_int32_t format); 59static int esschan_setspeed(void *data, u_int32_t speed); 60static int esschan_setblocksize(void *data, u_int32_t blocksize); 61static int esschan_trigger(void *data, int go); 62static int esschan_getptr(void *data); 63static pcmchan_caps *esschan_getcaps(void *data); 64 | |
65static pcmchan_caps sb_playcaps = { 66 4000, 22050, 67 AFMT_U8, 68 AFMT_U8 69}; 70 71static pcmchan_caps sb_reccaps = { 72 4000, 13000, --- 26 unchanged lines hidden (view full) --- 99}; 100 101static pcmchan_caps sb16x_caps = { 102 5000, 49000, 103 AFMT_STEREO | AFMT_U8 | AFMT_S16_LE, 104 AFMT_STEREO | AFMT_S16_LE 105}; 106 | 54static pcmchan_caps sb_playcaps = { 55 4000, 22050, 56 AFMT_U8, 57 AFMT_U8 58}; 59 60static pcmchan_caps sb_reccaps = { 61 4000, 13000, --- 26 unchanged lines hidden (view full) --- 88}; 89 90static pcmchan_caps sb16x_caps = { 91 5000, 49000, 92 AFMT_STEREO | AFMT_U8 | AFMT_S16_LE, 93 AFMT_STEREO | AFMT_S16_LE 94}; 95 |
107static pcmchan_caps ess_playcaps = { 108 5000, 49000, 109 AFMT_STEREO | AFMT_U8 | AFMT_S16_LE, 110 AFMT_STEREO | AFMT_S16_LE 111}; 112 113static pcmchan_caps ess_reccaps = { 114 5000, 49000, 115 AFMT_STEREO | AFMT_U8 | AFMT_S16_LE, 116 AFMT_STEREO | AFMT_S16_LE 117}; 118 | |
119static pcm_channel sb_chantemplate = { 120 sbchan_init, 121 sbchan_setdir, 122 sbchan_setformat, 123 sbchan_setspeed, 124 sbchan_setblocksize, 125 sbchan_trigger, 126 sbchan_getptr, 127 sbchan_getcaps, 128}; 129 | 96static pcm_channel sb_chantemplate = { 97 sbchan_init, 98 sbchan_setdir, 99 sbchan_setformat, 100 sbchan_setspeed, 101 sbchan_setblocksize, 102 sbchan_trigger, 103 sbchan_getptr, 104 sbchan_getcaps, 105}; 106 |
130static pcm_channel ess_chantemplate = { 131 esschan_init, 132 esschan_setdir, 133 esschan_setformat, 134 esschan_setspeed, 135 esschan_setblocksize, 136 esschan_trigger, 137 esschan_getptr, 138 esschan_getcaps, 139}; 140 | |
141struct sb_info; 142 143struct sb_chinfo { 144 struct sb_info *parent; 145 pcm_channel *channel; 146 snd_dbuf *buffer; 147 int dir; 148 u_int32_t fmt, spd; | 107struct sb_info; 108 109struct sb_chinfo { 110 struct sb_info *parent; 111 pcm_channel *channel; 112 snd_dbuf *buffer; 113 int dir; 114 u_int32_t fmt, spd; |
149 int ess_dma_started; | |
150}; 151 152struct sb_info { 153 struct resource *io_base; /* I/O address for the board */ 154 struct resource *irq; 155 struct resource *drq1; 156 struct resource *drq2; 157 bus_dma_tag_t parent_dmat; --- 14 unchanged lines hidden (view full) --- 172static int sb_getmixer(struct sb_info *sb, u_int port); 173static int sb_reset_dsp(struct sb_info *sb); 174 175static void sb_intr(void *arg); 176static int sb_speed(struct sb_chinfo *ch); 177static int sb_start(struct sb_chinfo *ch); 178static int sb_stop(struct sb_chinfo *ch); 179 | 115}; 116 117struct sb_info { 118 struct resource *io_base; /* I/O address for the board */ 119 struct resource *irq; 120 struct resource *drq1; 121 struct resource *drq2; 122 bus_dma_tag_t parent_dmat; --- 14 unchanged lines hidden (view full) --- 137static int sb_getmixer(struct sb_info *sb, u_int port); 138static int sb_reset_dsp(struct sb_info *sb); 139 140static void sb_intr(void *arg); 141static int sb_speed(struct sb_chinfo *ch); 142static int sb_start(struct sb_chinfo *ch); 143static int sb_stop(struct sb_chinfo *ch); 144 |
180static int ess_write(struct sb_info *sb, u_char reg, int val); 181static int ess_read(struct sb_info *sb, u_char reg); 182static void ess_intr(void *arg); 183static int ess_format(struct sb_chinfo *ch, u_int32_t format); 184static int ess_speed(struct sb_chinfo *ch, int speed); 185static int ess_start(struct sb_chinfo *ch); 186static int ess_stop(struct sb_chinfo *ch); 187static int ess_abort(struct sb_chinfo *ch); 188 | |
189static int sbmix_init(snd_mixer *m); 190static int sbmix_set(snd_mixer *m, unsigned dev, unsigned left, unsigned right); 191static int sbmix_setrecsrc(snd_mixer *m, u_int32_t src); 192 193static snd_mixer sb_mixer = { 194 "SoundBlaster mixer", 195 sbmix_init, 196 sbmix_set, --- 139 unchanged lines hidden (view full) --- 336 return sb_rd(sb, DSP_READ); 337 else 338 DELAY(20); 339 } 340 return 0xffff; 341} 342 343static int | 145static int sbmix_init(snd_mixer *m); 146static int sbmix_set(snd_mixer *m, unsigned dev, unsigned left, unsigned right); 147static int sbmix_setrecsrc(snd_mixer *m, u_int32_t src); 148 149static snd_mixer sb_mixer = { 150 "SoundBlaster mixer", 151 sbmix_init, 152 sbmix_set, --- 139 unchanged lines hidden (view full) --- 292 return sb_rd(sb, DSP_READ); 293 else 294 DELAY(20); 295 } 296 return 0xffff; 297} 298 299static int |
344ess_write(struct sb_info *sb, u_char reg, int val) 345{ 346 return sb_cmd1(sb, reg, val); 347} 348 349static int 350ess_read(struct sb_info *sb, u_char reg) 351{ 352 return (sb_cmd(sb, 0xc0) && sb_cmd(sb, reg))? sb_get_byte(sb) : 0xffff; 353} 354 355static int | |
356sb_reset_dsp(struct sb_info *sb) 357{ 358 sb_wr(sb, SBDSP_RST, 3); 359 DELAY(100); 360 sb_wr(sb, SBDSP_RST, 0); 361 if (sb_get_byte(sb) != 0xAA) { 362 DEB(printf("sb_reset_dsp 0x%lx failed\n", 363 rman_get_start(d->io_base))); --- 43 unchanged lines hidden (view full) --- 407 &rid, 0, ~0, 1, 408 RF_ACTIVE); 409 rid = 0; 410 if (!sb->drq1) 411 sb->drq1 = bus_alloc_resource(dev, SYS_RES_DRQ, 412 &rid, 0, ~0, 1, 413 RF_ACTIVE); 414 rid = 1; | 300sb_reset_dsp(struct sb_info *sb) 301{ 302 sb_wr(sb, SBDSP_RST, 3); 303 DELAY(100); 304 sb_wr(sb, SBDSP_RST, 0); 305 if (sb_get_byte(sb) != 0xAA) { 306 DEB(printf("sb_reset_dsp 0x%lx failed\n", 307 rman_get_start(d->io_base))); --- 43 unchanged lines hidden (view full) --- 351 &rid, 0, ~0, 1, 352 RF_ACTIVE); 353 rid = 0; 354 if (!sb->drq1) 355 sb->drq1 = bus_alloc_resource(dev, SYS_RES_DRQ, 356 &rid, 0, ~0, 1, 357 RF_ACTIVE); 358 rid = 1; |
415 if (!sb->drq2 && !(sb->bd_flags & BD_F_ESS)) | 359 if (!sb->drq2) |
416 sb->drq2 = bus_alloc_resource(dev, SYS_RES_DRQ, 417 &rid, 0, ~0, 1, 418 RF_ACTIVE); 419 420 if (sb->io_base && sb->drq1 && sb->irq) { | 360 sb->drq2 = bus_alloc_resource(dev, SYS_RES_DRQ, 361 &rid, 0, ~0, 1, 362 RF_ACTIVE); 363 364 if (sb->io_base && sb->drq1 && sb->irq) { |
421 int bs = (sb->bd_flags & BD_F_ESS)? ESS_BUFFSIZE : DSP_BUFFSIZE; | 365 int bs = DSP_BUFFSIZE; |
422 423 isa_dma_acquire(rman_get_start(sb->drq1)); 424 isa_dmainit(rman_get_start(sb->drq1), bs); 425 426 if (sb->drq2) { 427 isa_dma_acquire(rman_get_start(sb->drq2)); 428 isa_dmainit(rman_get_start(sb->drq2), bs); 429 } --- 13 unchanged lines hidden (view full) --- 443 int swp = 0; 444 445 if (!pb && !rb) { 446 if (dir == PCMDIR_PLAY && pc < 4) 447 swp = 1; 448 else 449 if (dir == PCMDIR_REC && rc < 4) 450 swp = 1; | 366 367 isa_dma_acquire(rman_get_start(sb->drq1)); 368 isa_dmainit(rman_get_start(sb->drq1), bs); 369 370 if (sb->drq2) { 371 isa_dma_acquire(rman_get_start(sb->drq2)); 372 isa_dmainit(rman_get_start(sb->drq2), bs); 373 } --- 13 unchanged lines hidden (view full) --- 387 int swp = 0; 388 389 if (!pb && !rb) { 390 if (dir == PCMDIR_PLAY && pc < 4) 391 swp = 1; 392 else 393 if (dir == PCMDIR_REC && rc < 4) 394 swp = 1; |
451 if (sb->bd_flags & BD_F_SB16X) 452 swp = !swp; 453 if (swp) { | 395 if (swp) { |
454 int t; 455 456 t = sb->pch.buffer->chan; 457 sb->pch.buffer->chan = sb->rch.buffer->chan; 458 sb->rch.buffer->chan = t; 459 sb->pch.buffer->dir = ISADMA_WRITE; 460 sb->rch.buffer->dir = ISADMA_READ; 461 } 462 } 463} 464 465static int 466sb_doattach(device_t dev, struct sb_info *sb) 467{ 468 snddev_info *d = device_get_softc(dev); 469 void *ih; 470 char status[SND_STATUSLEN]; | 396 int t; 397 398 t = sb->pch.buffer->chan; 399 sb->pch.buffer->chan = sb->rch.buffer->chan; 400 sb->rch.buffer->chan = t; 401 sb->pch.buffer->dir = ISADMA_WRITE; 402 sb->rch.buffer->dir = ISADMA_READ; 403 } 404 } 405} 406 407static int 408sb_doattach(device_t dev, struct sb_info *sb) 409{ 410 snddev_info *d = device_get_softc(dev); 411 void *ih; 412 char status[SND_STATUSLEN]; |
471 int bs = (sb->bd_flags & BD_F_ESS)? ESS_BUFFSIZE : DSP_BUFFSIZE; | 413 int bs = DSP_BUFFSIZE; |
472 473 if (sb_alloc_resources(sb, dev)) 474 goto no; 475 if (sb_reset_dsp(sb)) 476 goto no; 477 mixer_init(d, &sb_mixer, sb); 478 | 414 415 if (sb_alloc_resources(sb, dev)) 416 goto no; 417 if (sb_reset_dsp(sb)) 418 goto no; 419 mixer_init(d, &sb_mixer, sb); 420 |
479 if (sb->bd_flags & BD_F_ESS) 480 bus_setup_intr(dev, sb->irq, INTR_TYPE_TTY, ess_intr, sb, &ih); 481 else 482 bus_setup_intr(dev, sb->irq, INTR_TYPE_TTY, sb_intr, sb, &ih); | 421 bus_setup_intr(dev, sb->irq, INTR_TYPE_TTY, sb_intr, sb, &ih); |
483 if ((sb->bd_flags & BD_F_SB16) && !(sb->bd_flags & BD_F_SB16X)) 484 pcm_setswap(dev, sb16_swap); 485 if (!sb->drq2) 486 pcm_setflags(dev, pcm_getflags(dev) | SD_F_SIMPLEX); 487 488 if (bus_dma_tag_create(/*parent*/NULL, /*alignment*/2, /*boundary*/0, 489 /*lowaddr*/BUS_SPACE_MAXADDR_24BIT, 490 /*highaddr*/BUS_SPACE_MAXADDR, --- 9 unchanged lines hidden (view full) --- 500 rman_get_start(sb->io_base), rman_get_start(sb->irq), 501 rman_get_start(sb->drq1)); 502 if (sb->drq2) 503 snprintf(status + strlen(status), SND_STATUSLEN - strlen(status), 504 ":%ld", rman_get_start(sb->drq2)); 505 506 if (pcm_register(dev, sb, 1, 1)) 507 goto no; | 422 if ((sb->bd_flags & BD_F_SB16) && !(sb->bd_flags & BD_F_SB16X)) 423 pcm_setswap(dev, sb16_swap); 424 if (!sb->drq2) 425 pcm_setflags(dev, pcm_getflags(dev) | SD_F_SIMPLEX); 426 427 if (bus_dma_tag_create(/*parent*/NULL, /*alignment*/2, /*boundary*/0, 428 /*lowaddr*/BUS_SPACE_MAXADDR_24BIT, 429 /*highaddr*/BUS_SPACE_MAXADDR, --- 9 unchanged lines hidden (view full) --- 439 rman_get_start(sb->io_base), rman_get_start(sb->irq), 440 rman_get_start(sb->drq1)); 441 if (sb->drq2) 442 snprintf(status + strlen(status), SND_STATUSLEN - strlen(status), 443 ":%ld", rman_get_start(sb->drq2)); 444 445 if (pcm_register(dev, sb, 1, 1)) 446 goto no; |
508 if (sb->bd_flags & BD_F_ESS) { 509 pcm_addchan(dev, PCMDIR_REC, &ess_chantemplate, sb); 510 pcm_addchan(dev, PCMDIR_PLAY, &ess_chantemplate, sb); 511 } else { 512 pcm_addchan(dev, PCMDIR_REC, &sb_chantemplate, sb); 513 pcm_addchan(dev, PCMDIR_PLAY, &sb_chantemplate, sb); 514 } | 447 pcm_addchan(dev, PCMDIR_REC, &sb_chantemplate, sb); 448 pcm_addchan(dev, PCMDIR_PLAY, &sb_chantemplate, sb); |
515 pcm_setstatus(dev, status); 516 517 return 0; 518 519no: 520 sb_release_resources(sb, dev); 521 return ENXIO; 522} --- 38 unchanged lines hidden (view full) --- 561 if ((reason & 2) && (sb->rch.buffer->dl > 0)) 562 chn_intr(sb->rch.channel); 563 if (c & 1) 564 sb_rd(sb, DSP_DATA_AVAIL); /* 8-bit int ack */ 565 if (c & 2) 566 sb_rd(sb, DSP_DATA_AVL16); /* 16-bit int ack */ 567} 568 | 449 pcm_setstatus(dev, status); 450 451 return 0; 452 453no: 454 sb_release_resources(sb, dev); 455 return ENXIO; 456} --- 38 unchanged lines hidden (view full) --- 495 if ((reason & 2) && (sb->rch.buffer->dl > 0)) 496 chn_intr(sb->rch.channel); 497 if (c & 1) 498 sb_rd(sb, DSP_DATA_AVAIL); /* 8-bit int ack */ 499 if (c & 2) 500 sb_rd(sb, DSP_DATA_AVL16); /* 16-bit int ack */ 501} 502 |
569static void 570ess_intr(void *arg) 571{ 572 struct sb_info *sb = (struct sb_info *)arg; 573 574 sb_rd(sb, DSP_DATA_AVAIL); /* int ack */ 575#ifdef notyet 576 /* 577 * XXX 578 * for full-duplex mode: 579 * should read port 0x6 to identify where interrupt came from. 580 */ 581#endif 582 /* 583 * We are transferring data in DSP normal mode, 584 * so clear the dl to indicate the DMA is stopped. 585 */ 586 if (sb->pch.buffer->dl > 0) 587 chn_intr(sb->pch.channel); 588 if (sb->rch.buffer->dl > 0) 589 chn_intr(sb->rch.channel); 590} 591 | |
592static int 593sb_speed(struct sb_chinfo *ch) 594{ 595 struct sb_info *sb = ch->parent; 596 int play = (ch->dir == PCMDIR_PLAY)? 1 : 0; 597 int stereo = (ch->fmt & AFMT_STEREO)? 1 : 0; 598 int speed = ch->spd; 599 --- 208 unchanged lines hidden (view full) --- 808 else if (ch->parent->bd_id < 0x400) 809 return p? &sbpro_playcaps : &sbpro_reccaps; 810 else if (ch->parent->bd_flags & BD_F_SB16X) 811 return &sb16x_caps; 812 else 813 return (ch->buffer->chan >= 4)? &sb16_hcaps : &sb16_lcaps; 814} 815 | 503static int 504sb_speed(struct sb_chinfo *ch) 505{ 506 struct sb_info *sb = ch->parent; 507 int play = (ch->dir == PCMDIR_PLAY)? 1 : 0; 508 int stereo = (ch->fmt & AFMT_STEREO)? 1 : 0; 509 int speed = ch->spd; 510 --- 208 unchanged lines hidden (view full) --- 719 else if (ch->parent->bd_id < 0x400) 720 return p? &sbpro_playcaps : &sbpro_reccaps; 721 else if (ch->parent->bd_flags & BD_F_SB16X) 722 return &sb16x_caps; 723 else 724 return (ch->buffer->chan >= 4)? &sb16_hcaps : &sb16_lcaps; 725} 726 |
816/* utility functions for ESS */ 817static int 818ess_format(struct sb_chinfo *ch, u_int32_t format) 819{ 820 struct sb_info *sb = ch->parent; 821 int play = (ch->dir == PCMDIR_PLAY)? 1 : 0; 822 int b16 = (format & AFMT_S16_LE)? 1 : 0; 823 int stereo = (format & AFMT_STEREO)? 1 : 0; 824 u_char c; 825 826 ch->fmt = format; 827 sb_reset_dsp(sb); 828 /* auto-init DMA mode */ 829 ess_write(sb, 0xb8, play ? 0x04 : 0x0e); 830 /* mono/stereo */ 831 c = (ess_read(sb, 0xa8) & ~0x03) | 1; 832 if (!stereo) 833 c++; 834 ess_write(sb, 0xa8, c); 835 /* demand mode, 4 bytes/xfer */ 836 ess_write(sb, 0xb9, 2); 837 /* setup dac/adc */ 838 if (play) 839 ess_write(sb, 0xb6, b16? 0x00 : 0x80); 840 ess_write(sb, 0xb7, 0x51 | (b16? 0x20 : 0x00)); 841 ess_write(sb, 0xb7, 0x98 + (b16? 0x24 : 0x00) + (stereo? 0x00 : 0x38)); 842 /* irq/drq control */ 843 ess_write(sb, 0xb1, (ess_read(sb, 0xb1) & 0x0f) | 0x50); 844 ess_write(sb, 0xb2, (ess_read(sb, 0xb2) & 0x0f) | 0x50); 845 return 0; 846} 847 848static int 849ess_speed(struct sb_chinfo *ch, int speed) 850{ 851 struct sb_info *sb = ch->parent; 852 int t; 853 854 RANGE (speed, 5000, 49000); 855 if (speed > 22000) { 856 t = (795500 + speed / 2) / speed; 857 speed = (795500 + t / 2) / t; 858 t = (256 - t ) | 0x80; 859 } else { 860 t = (397700 + speed / 2) / speed; 861 speed = (397700 + t / 2) / t; 862 t = 128 - t; 863 } 864 ess_write(sb, 0xa1, t); /* set time constant */ 865#if 0 866 d->play_speed = d->rec_speed = speed; 867 speed = (speed * 9 ) / 20; 868#endif 869 t = 256 - 7160000 / ((speed * 9 / 20) * 82); 870 ess_write(sb, 0xa2, t); 871 return speed; 872} 873 874static int 875ess_start(struct sb_chinfo *ch) 876{ 877 struct sb_info *sb = ch->parent; 878 int play = (ch->dir == PCMDIR_PLAY)? 1 : 0; 879 short c = - ch->buffer->dl; 880 u_char c1; 881 882 /* 883 * clear bit 0 of register B8h 884 */ 885#if 1 886 c1 = play ? 0x04 : 0x0e; 887 ess_write(sb, 0xb8, c1++); 888#else 889 c1 = ess_read(sb, 0xb8) & 0xfe; 890 ess_write(sb, 0xb8, c1++); 891#endif 892 /* 893 * update ESS Transfer Count Register 894 */ 895 ess_write(sb, 0xa4, (u_char)((u_short)c & 0xff)); 896 ess_write(sb, 0xa5, (u_char)(((u_short)c >> 8) & 0xff)); 897 /* 898 * set bit 0 of register B8h 899 */ 900 ess_write(sb, 0xb8, c1); 901 if (play) 902 sb_cmd(sb, DSP_CMD_SPKON); 903 return 0; 904} 905 906static int 907ess_stop(struct sb_chinfo *ch) 908{ 909 struct sb_info *sb = ch->parent; 910 /* 911 * no need to send a stop command if the DMA has already stopped. 912 */ 913 if (ch->buffer->dl > 0) { 914 sb_cmd(sb, DSP_CMD_DMAPAUSE_8); /* pause dma. */ 915 } 916 return 0; 917} 918 919static int 920ess_abort(struct sb_chinfo *ch) 921{ 922 struct sb_info *sb = ch->parent; 923 int play = (ch->dir == PCMDIR_PLAY)? 1 : 0; 924 925 if (play) 926 sb_cmd(sb, DSP_CMD_SPKOFF); /* speaker off */ 927 sb_reset_dsp(sb); 928 ess_format(ch, ch->fmt); 929 ess_speed(ch, ch->channel->speed); 930 return 0; 931} 932 933/* channel interface for ESS18xx */ 934static void * 935esschan_init(void *devinfo, snd_dbuf *b, pcm_channel *c, int dir) 936{ 937 struct sb_info *sb = devinfo; 938 struct sb_chinfo *ch = (dir == PCMDIR_PLAY)? &sb->pch : &sb->rch; 939 940 ch->parent = sb; 941 ch->channel = c; 942 ch->buffer = b; 943 ch->buffer->bufsize = ESS_BUFFSIZE; 944 if (chn_allocbuf(ch->buffer, sb->parent_dmat) == -1) 945 return NULL; 946 ch->buffer->chan = rman_get_start(sb->drq1); 947 return ch; 948} 949 950static int 951esschan_setdir(void *data, int dir) 952{ 953 struct sb_chinfo *ch = data; 954 955 ch->dir = dir; 956 return 0; 957} 958 959static int 960esschan_setformat(void *data, u_int32_t format) 961{ 962 struct sb_chinfo *ch = data; 963 964 ess_format(ch, format); 965 return 0; 966} 967 968static int 969esschan_setspeed(void *data, u_int32_t speed) 970{ 971 struct sb_chinfo *ch = data; 972 973 return ess_speed(ch, speed); 974} 975 976static int 977esschan_setblocksize(void *data, u_int32_t blocksize) 978{ 979 return blocksize; 980} 981 982static int 983esschan_trigger(void *data, int go) 984{ 985 struct sb_chinfo *ch = data; 986 987 if (go == PCMTRIG_EMLDMAWR) 988 return 0; 989 switch (go) { 990 case PCMTRIG_START: 991 if (!ch->ess_dma_started) 992 buf_isadma(ch->buffer, go); 993 ch->ess_dma_started = 1; 994 ess_start(ch); 995 break; 996 case PCMTRIG_STOP: 997 if (ch->buffer->dl >= 0) { 998 buf_isadma(ch->buffer, go); 999 ch->ess_dma_started = 0; 1000 ess_stop(ch); 1001 } 1002 break; 1003 case PCMTRIG_ABORT: 1004 default: 1005 ch->ess_dma_started = 0; 1006 ess_abort(ch); 1007 buf_isadma(ch->buffer, go); 1008 break; 1009 } 1010 return 0; 1011} 1012 1013static int 1014esschan_getptr(void *data) 1015{ 1016 struct sb_chinfo *ch = data; 1017 1018 return buf_isadmaptr(ch->buffer); 1019} 1020 1021static pcmchan_caps * 1022esschan_getcaps(void *data) 1023{ 1024 struct sb_chinfo *ch = data; 1025 1026 return (ch->dir == PCMDIR_PLAY)? &ess_playcaps : &ess_reccaps; 1027} 1028 | |
1029/************************************************************/ 1030 1031static int 1032sbmix_init(snd_mixer *m) 1033{ 1034 struct sb_info *sb = mix_getdevinfo(m); 1035 1036 switch (sb->bd_flags & BD_F_MIX_MASK) { 1037 case BD_F_MIX_CT1345: /* SB 3.0 has 1345 mixer */ 1038 mix_setdevs(m, SBPRO_MIXER_DEVICES); 1039 mix_setrecdevs(m, SBPRO_RECORDING_DEVICES); 1040 sb_setmixer(sb, 0, 1); /* reset mixer */ | 727/************************************************************/ 728 729static int 730sbmix_init(snd_mixer *m) 731{ 732 struct sb_info *sb = mix_getdevinfo(m); 733 734 switch (sb->bd_flags & BD_F_MIX_MASK) { 735 case BD_F_MIX_CT1345: /* SB 3.0 has 1345 mixer */ 736 mix_setdevs(m, SBPRO_MIXER_DEVICES); 737 mix_setrecdevs(m, SBPRO_RECORDING_DEVICES); 738 sb_setmixer(sb, 0, 1); /* reset mixer */ |
1041 if (!(sb->bd_flags & BD_F_ESS)) 1042 sb_setmixer(sb, MIC_VOL, 0x6); /* mic volume max */ | 739 sb_setmixer(sb, MIC_VOL, 0x6); /* mic volume max */ |
1043 sb_setmixer(sb, RECORD_SRC, 0x0); /* mic source */ 1044 sb_setmixer(sb, FM_VOL, 0x0); /* no midi */ 1045 break; 1046 1047 case BD_F_MIX_CT1745: /* SB16 mixer ... */ 1048 mix_setdevs(m, SB16_MIXER_DEVICES); 1049 mix_setrecdevs(m, SB16_RECORDING_DEVICES); 1050 sb_setmixer(sb, 0x3c, 0x1f); /* make all output active */ --- 8 unchanged lines hidden (view full) --- 1059{ 1060 struct sb_info *sb = mix_getdevinfo(m); 1061 int regoffs; 1062 u_char val; 1063 mixer_tab *iomap; 1064 1065 switch (sb->bd_flags & BD_F_MIX_MASK) { 1066 case BD_F_MIX_CT1345: | 740 sb_setmixer(sb, RECORD_SRC, 0x0); /* mic source */ 741 sb_setmixer(sb, FM_VOL, 0x0); /* no midi */ 742 break; 743 744 case BD_F_MIX_CT1745: /* SB16 mixer ... */ 745 mix_setdevs(m, SB16_MIXER_DEVICES); 746 mix_setrecdevs(m, SB16_RECORDING_DEVICES); 747 sb_setmixer(sb, 0x3c, 0x1f); /* make all output active */ --- 8 unchanged lines hidden (view full) --- 756{ 757 struct sb_info *sb = mix_getdevinfo(m); 758 int regoffs; 759 u_char val; 760 mixer_tab *iomap; 761 762 switch (sb->bd_flags & BD_F_MIX_MASK) { 763 case BD_F_MIX_CT1345: |
1067 if (sb->bd_flags & BD_F_ESS) 1068 iomap = &ess_mix; 1069 else 1070 iomap = &sbpro_mix; | 764 iomap = &sbpro_mix; |
1071 break; 1072 1073 case BD_F_MIX_CT1745: 1074 iomap = &sb16_mix; 1075 break; 1076 1077 default: 1078 return -1; --- 74 unchanged lines hidden (view full) --- 1153 /* The parent device has already been probed. */ 1154 r = BUS_READ_IVAR(device_get_parent(dev), dev, 0, &func); 1155 if (func != SCF_PCM) 1156 return (ENXIO); 1157 1158 r = BUS_READ_IVAR(device_get_parent(dev), dev, 1, &ver); 1159 f = (ver & 0xffff0000) >> 16; 1160 ver &= 0x0000ffff; | 765 break; 766 767 case BD_F_MIX_CT1745: 768 iomap = &sb16_mix; 769 break; 770 771 default: 772 return -1; --- 74 unchanged lines hidden (view full) --- 847 /* The parent device has already been probed. */ 848 r = BUS_READ_IVAR(device_get_parent(dev), dev, 0, &func); 849 if (func != SCF_PCM) 850 return (ENXIO); 851 852 r = BUS_READ_IVAR(device_get_parent(dev), dev, 1, &ver); 853 f = (ver & 0xffff0000) >> 16; 854 ver &= 0x0000ffff; |
1161 snprintf(buf, sizeof buf, "SB DSP %d.%02d%s%s", (int) ver >> 8, (int) ver & 0xff, 1162 (f & BD_F_ESS)? " (ESS mode)" : "", | 855 if (f & BD_F_ESS) 856 return (ENXIO); 857 858 snprintf(buf, sizeof buf, "SB DSP %d.%02d%s", (int) ver >> 8, (int) ver & 0xff, |
1163 (f & BD_F_SB16X)? " (ViBRA16X)" : ""); 1164 device_set_desc_copy(dev, buf); 1165 1166 return 0; 1167} 1168 1169static int 1170sbsbc_attach(device_t dev) --- 34 unchanged lines hidden --- | 859 (f & BD_F_SB16X)? " (ViBRA16X)" : ""); 860 device_set_desc_copy(dev, buf); 861 862 return 0; 863} 864 865static int 866sbsbc_attach(device_t dev) --- 34 unchanged lines hidden --- |