37 38#define SOLO_DEFAULT_BUFSZ 16384 39#define ABS(x) (((x) < 0)? -(x) : (x)) 40 41/* if defined, playback always uses the 2nd channel and full duplex works */ 42#undef ESS18XX_DUPLEX 43 44/* more accurate clocks and split audio1/audio2 rates */ 45#define ESS18XX_NEWSPEED 46 47static u_int32_t ess_playfmt[] = { 48 AFMT_U8, 49 AFMT_STEREO | AFMT_U8, 50 AFMT_S8, 51 AFMT_STEREO | AFMT_S8, 52 AFMT_S16_LE, 53 AFMT_STEREO | AFMT_S16_LE, 54 AFMT_U16_LE, 55 AFMT_STEREO | AFMT_U16_LE, 56 0 57}; 58static struct pcmchan_caps ess_playcaps = {5000, 49000, ess_playfmt, 0}; 59 60/* 61 * Recording output is byte-swapped 62 */ 63static u_int32_t ess_recfmt[] = { 64 AFMT_U8, 65 AFMT_STEREO | AFMT_U8, 66 AFMT_S8, 67 AFMT_STEREO | AFMT_S8, 68 AFMT_S16_BE, 69 AFMT_STEREO | AFMT_S16_BE, 70 AFMT_U16_BE, 71 AFMT_STEREO | AFMT_U16_BE, 72 0 73}; 74static struct pcmchan_caps ess_reccaps = {5000, 49000, ess_recfmt, 0}; 75 76struct ess_info; 77 78struct ess_chinfo { 79 struct ess_info *parent; 80 struct pcm_channel *channel; 81 struct snd_dbuf *buffer; 82 int dir, hwch, stopping; 83 u_int32_t fmt, spd, blksz; 84}; 85 86struct ess_info { 87 struct resource *io, *sb, *vc, *mpu, *gp; /* I/O address for the board */ 88 struct resource *irq; 89 void *ih; 90 bus_dma_tag_t parent_dmat; 91 92 int simplex_dir, type, duplex:1, newspeed:1, dmasz[2]; 93 unsigned int bufsz; 94 95 struct ess_chinfo pch, rch; 96}; 97 98static int ess_rd(struct ess_info *sc, int reg); 99static void ess_wr(struct ess_info *sc, int reg, u_int8_t val); 100static int ess_dspready(struct ess_info *sc); 101static int ess_cmd(struct ess_info *sc, u_char val); 102static int ess_cmd1(struct ess_info *sc, u_char cmd, int val); 103static int ess_get_byte(struct ess_info *sc); 104static void ess_setmixer(struct ess_info *sc, u_int port, u_int value); 105static int ess_getmixer(struct ess_info *sc, u_int port); 106static int ess_reset_dsp(struct ess_info *sc); 107 108static int ess_write(struct ess_info *sc, u_char reg, int val); 109static int ess_read(struct ess_info *sc, u_char reg); 110 111static void ess_intr(void *arg); 112static int ess_setupch(struct ess_info *sc, int ch, int dir, int spd, u_int32_t fmt, int len); 113static int ess_start(struct ess_chinfo *ch); 114static int ess_stop(struct ess_chinfo *ch); 115 116static int ess_dmasetup(struct ess_info *sc, int ch, u_int32_t base, u_int16_t cnt, int dir); 117static int ess_dmapos(struct ess_info *sc, int ch); 118static int ess_dmatrigger(struct ess_info *sc, int ch, int go); 119 120/* 121 * Common code for the midi and pcm functions 122 * 123 * ess_cmd write a single byte to the CMD port. 124 * ess_cmd1 write a CMD + 1 byte arg 125 * ess_cmd2 write a CMD + 2 byte arg 126 * ess_get_byte returns a single byte from the DSP data port 127 * 128 * ess_write is actually ess_cmd1 129 * ess_read access ext. regs via ess_cmd(0xc0, reg) followed by ess_get_byte 130 */ 131 132static int 133port_rd(struct resource *port, int regno, int size) 134{ 135 bus_space_tag_t st = rman_get_bustag(port); 136 bus_space_handle_t sh = rman_get_bushandle(port); 137 138 switch (size) { 139 case 1: 140 return bus_space_read_1(st, sh, regno); 141 case 2: 142 return bus_space_read_2(st, sh, regno); 143 case 4: 144 return bus_space_read_4(st, sh, regno); 145 default: 146 return 0xffffffff; 147 } 148} 149 150static void 151port_wr(struct resource *port, int regno, u_int32_t data, int size) 152{ 153 bus_space_tag_t st = rman_get_bustag(port); 154 bus_space_handle_t sh = rman_get_bushandle(port); 155 156 switch (size) { 157 case 1: 158 bus_space_write_1(st, sh, regno, data); 159 break; 160 case 2: 161 bus_space_write_2(st, sh, regno, data); 162 break; 163 case 4: 164 bus_space_write_4(st, sh, regno, data); 165 break; 166 } 167} 168 169static int 170ess_rd(struct ess_info *sc, int reg) 171{ 172 return port_rd(sc->sb, reg, 1); 173} 174 175static void 176ess_wr(struct ess_info *sc, int reg, u_int8_t val) 177{ 178 port_wr(sc->sb, reg, val, 1); 179} 180 181static int 182ess_dspready(struct ess_info *sc) 183{ 184 return ((ess_rd(sc, SBDSP_STATUS) & 0x80) == 0); 185} 186 187static int 188ess_dspwr(struct ess_info *sc, u_char val) 189{ 190 int i; 191 192 for (i = 0; i < 1000; i++) { 193 if (ess_dspready(sc)) { 194 ess_wr(sc, SBDSP_CMD, val); 195 return 1; 196 } 197 if (i > 10) DELAY((i > 100)? 1000 : 10); 198 } 199 printf("ess_dspwr(0x%02x) timed out.\n", val); 200 return 0; 201} 202 203static int 204ess_cmd(struct ess_info *sc, u_char val) 205{ 206 DEB(printf("ess_cmd: %x\n", val)); 207 return ess_dspwr(sc, val); 208} 209 210static int 211ess_cmd1(struct ess_info *sc, u_char cmd, int val) 212{ 213 DEB(printf("ess_cmd1: %x, %x\n", cmd, val)); 214 if (ess_dspwr(sc, cmd)) { 215 return ess_dspwr(sc, val & 0xff); 216 } else return 0; 217} 218 219static void 220ess_setmixer(struct ess_info *sc, u_int port, u_int value) 221{ 222 u_long flags; 223 224 DEB(printf("ess_setmixer: reg=%x, val=%x\n", port, value);) 225 flags = spltty(); 226 ess_wr(sc, SB_MIX_ADDR, (u_char) (port & 0xff)); /* Select register */ 227 DELAY(10); 228 ess_wr(sc, SB_MIX_DATA, (u_char) (value & 0xff)); 229 DELAY(10); 230 splx(flags); 231} 232 233static int 234ess_getmixer(struct ess_info *sc, u_int port) 235{ 236 int val; 237 u_long flags; 238 239 flags = spltty(); 240 ess_wr(sc, SB_MIX_ADDR, (u_char) (port & 0xff)); /* Select register */ 241 DELAY(10); 242 val = ess_rd(sc, SB_MIX_DATA); 243 DELAY(10); 244 splx(flags); 245 246 return val; 247} 248 249static int 250ess_get_byte(struct ess_info *sc) 251{ 252 int i; 253 254 for (i = 1000; i > 0; i--) { 255 if (ess_rd(sc, 0xc) & 0x40) 256 return ess_rd(sc, DSP_READ); 257 else 258 DELAY(20); 259 } 260 return -1; 261} 262 263static int 264ess_write(struct ess_info *sc, u_char reg, int val) 265{ 266 return ess_cmd1(sc, reg, val); 267} 268 269static int 270ess_read(struct ess_info *sc, u_char reg) 271{ 272 return (ess_cmd(sc, 0xc0) && ess_cmd(sc, reg))? ess_get_byte(sc) : -1; 273} 274 275static int 276ess_reset_dsp(struct ess_info *sc) 277{ 278 DEB(printf("ess_reset_dsp\n")); 279 ess_wr(sc, SBDSP_RST, 3); 280 DELAY(100); 281 ess_wr(sc, SBDSP_RST, 0); 282 if (ess_get_byte(sc) != 0xAA) { 283 DEB(printf("ess_reset_dsp failed\n")); 284/* 285 rman_get_start(d->io_base))); 286*/ 287 return ENXIO; /* Sorry */ 288 } 289 ess_cmd(sc, 0xc6); 290 return 0; 291} 292 293static void 294ess_intr(void *arg) 295{ 296 struct ess_info *sc = (struct ess_info *)arg; 297 int src, pirq = 0, rirq = 0; 298 299 src = 0; 300 if (ess_getmixer(sc, 0x7a) & 0x80) 301 src |= 2; 302 if (ess_rd(sc, 0x0c) & 0x01) 303 src |= 1; 304 305 if (src == 0) 306 return; 307 308 if (sc->duplex) { 309 pirq = (src & sc->pch.hwch)? 1 : 0; 310 rirq = (src & sc->rch.hwch)? 1 : 0; 311 } else { 312 if (sc->simplex_dir == PCMDIR_PLAY) 313 pirq = 1; 314 if (sc->simplex_dir == PCMDIR_REC) 315 rirq = 1; 316 if (!pirq && !rirq) 317 printf("solo: IRQ neither playback nor rec!\n"); 318 } 319 320 DEB(printf("ess_intr: pirq:%d rirq:%d\n",pirq,rirq)); 321 322 if (pirq) { 323 if (sc->pch.stopping) { 324 ess_dmatrigger(sc, sc->pch.hwch, 0); 325 sc->pch.stopping = 0; 326 if (sc->pch.hwch == 1) 327 ess_write(sc, 0xb8, ess_read(sc, 0xb8) & ~0x01); 328 else 329 ess_setmixer(sc, 0x78, ess_getmixer(sc, 0x78) & ~0x03); 330 } 331 chn_intr(sc->pch.channel); 332 } 333 334 if (rirq) { 335 if (sc->rch.stopping) { 336 ess_dmatrigger(sc, sc->rch.hwch, 0); 337 sc->rch.stopping = 0; 338 /* XXX: will this stop audio2? */ 339 ess_write(sc, 0xb8, ess_read(sc, 0xb8) & ~0x01); 340 } 341 chn_intr(sc->rch.channel); 342 } 343 344 if (src & 2) 345 ess_setmixer(sc, 0x7a, ess_getmixer(sc, 0x7a) & ~0x80); 346 if (src & 1) 347 ess_rd(sc, DSP_DATA_AVAIL); 348} 349 350/* utility functions for ESS */ 351static u_int8_t 352ess_calcspeed8(int *spd) 353{ 354 int speed = *spd; 355 u_int32_t t; 356 357 if (speed > 22000) { 358 t = (795500 + speed / 2) / speed; 359 speed = (795500 + t / 2) / t; 360 t = (256 - t) | 0x80; 361 } else { 362 t = (397700 + speed / 2) / speed; 363 speed = (397700 + t / 2) / t; 364 t = 128 - t; 365 } 366 *spd = speed; 367 return t & 0x000000ff; 368} 369 370static u_int8_t 371ess_calcspeed9(int *spd) 372{ 373 int speed, s0, s1, use0; 374 u_int8_t t0, t1; 375 376 /* rate = source / (256 - divisor) */ 377 /* divisor = 256 - (source / rate) */ 378 speed = *spd; 379 t0 = 128 - (793800 / speed); 380 s0 = 793800 / (128 - t0); 381 382 t1 = 128 - (768000 / speed); 383 s1 = 768000 / (128 - t1); 384 t1 |= 0x80; 385 386 use0 = (ABS(speed - s0) < ABS(speed - s1))? 1 : 0; 387 388 *spd = use0? s0 : s1; 389 return use0? t0 : t1; 390} 391 392static u_int8_t 393ess_calcfilter(int spd) 394{ 395 int cutoff; 396 397 /* cutoff = 7160000 / (256 - divisor) */ 398 /* divisor = 256 - (7160000 / cutoff) */ 399 cutoff = (spd * 9 * 82) / 20; 400 return (256 - (7160000 / cutoff)); 401} 402 403static int 404ess_setupch(struct ess_info *sc, int ch, int dir, int spd, u_int32_t fmt, int len) 405{ 406 int play = (dir == PCMDIR_PLAY)? 1 : 0; 407 int b16 = (fmt & AFMT_16BIT)? 1 : 0; 408 int stereo = (fmt & AFMT_STEREO)? 1 : 0; 409 int unsign = (fmt == AFMT_U8 || fmt == AFMT_U16_LE || fmt == AFMT_U16_BE)? 1 : 0; 410 u_int8_t spdval, fmtval; 411 412 DEB(printf("ess_setupch\n")); 413 spdval = (sc->newspeed)? ess_calcspeed9(&spd) : ess_calcspeed8(&spd); 414 415 sc->simplex_dir = play ? PCMDIR_PLAY : PCMDIR_REC ; 416 417 if (ch == 1) { 418 KASSERT((dir == PCMDIR_PLAY) || (dir == PCMDIR_REC), ("ess_setupch: dir1 bad")); 419 len = -len; 420 /* transfer length low */ 421 ess_write(sc, 0xa4, len & 0x00ff); 422 /* transfer length high */ 423 ess_write(sc, 0xa5, (len & 0xff00) >> 8); 424 /* autoinit, dma dir */ 425 ess_write(sc, 0xb8, 0x04 | (play? 0x00 : 0x0a)); 426 /* mono/stereo */ 427 ess_write(sc, 0xa8, (ess_read(sc, 0xa8) & ~0x03) | (stereo? 0x01 : 0x02)); 428 /* demand mode, 4 bytes/xfer */ 429 ess_write(sc, 0xb9, 0x02); 430 /* sample rate */ 431 ess_write(sc, 0xa1, spdval); 432 /* filter cutoff */ 433 ess_write(sc, 0xa2, ess_calcfilter(spd)); 434 /* setup dac/adc */ 435 /* 436 if (play) 437 ess_write(sc, 0xb6, unsign? 0x80 : 0x00); 438 */ 439 /* mono, b16: signed, load signal */ 440 /* 441 ess_write(sc, 0xb7, 0x51 | (unsign? 0x00 : 0x20)); 442 */ 443 /* setup fifo */ 444 ess_write(sc, 0xb7, 0x91 | (unsign? 0x00 : 0x20) | 445 (b16? 0x04 : 0x00) | 446 (stereo? 0x08 : 0x40)); 447 /* irq control */ 448 ess_write(sc, 0xb1, (ess_read(sc, 0xb1) & 0x0f) | 0x50); 449 /* drq control */ 450 ess_write(sc, 0xb2, (ess_read(sc, 0xb2) & 0x0f) | 0x50); 451 } else if (ch == 2) { 452 KASSERT(dir == PCMDIR_PLAY, ("ess_setupch: dir2 bad")); 453 len >>= 1; 454 len = -len; 455 /* transfer length low */ 456 ess_setmixer(sc, 0x74, len & 0x00ff); 457 /* transfer length high */ 458 ess_setmixer(sc, 0x76, (len & 0xff00) >> 8); 459 /* autoinit, 4 bytes/req */ 460 ess_setmixer(sc, 0x78, 0x10); 461 fmtval = b16 | (stereo << 1) | ((!unsign) << 2); 462 /* enable irq, set format */ 463 ess_setmixer(sc, 0x7a, 0x40 | fmtval); 464 if (sc->newspeed) { 465 /* sample rate */ 466 ess_setmixer(sc, 0x70, spdval); 467 /* filter cutoff */ 468 ess_setmixer(sc, 0x72, ess_calcfilter(spd)); 469 } 470 471 } 472 return 0; 473} 474static int 475ess_start(struct ess_chinfo *ch) 476{ 477 struct ess_info *sc = ch->parent; 478 479 DEB(printf("ess_start\n");); 480 ess_setupch(sc, ch->hwch, ch->dir, ch->spd, ch->fmt, ch->blksz); 481 ch->stopping = 0; 482 if (ch->hwch == 1) { 483 ess_write(sc, 0xb8, ess_read(sc, 0xb8) | 0x01); 484 if (ch->dir == PCMDIR_PLAY) { 485#if 0 486 DELAY(100000); /* 100 ms */ 487#endif 488 ess_cmd(sc, 0xd1); 489 } 490 } else 491 ess_setmixer(sc, 0x78, ess_getmixer(sc, 0x78) | 0x03); 492 return 0; 493} 494 495static int 496ess_stop(struct ess_chinfo *ch) 497{ 498 struct ess_info *sc = ch->parent; 499 500 DEB(printf("ess_stop\n")); 501 ch->stopping = 1; 502 if (ch->hwch == 1) 503 ess_write(sc, 0xb8, ess_read(sc, 0xb8) & ~0x04); 504 else 505 ess_setmixer(sc, 0x78, ess_getmixer(sc, 0x78) & ~0x10); 506 DEB(printf("done with stop\n")); 507 return 0; 508} 509 510/* -------------------------------------------------------------------- */ 511/* channel interface for ESS18xx */ 512static void * 513esschan_init(kobj_t obj, void *devinfo, struct snd_dbuf *b, struct pcm_channel *c, int dir) 514{ 515 struct ess_info *sc = devinfo; 516 struct ess_chinfo *ch = (dir == PCMDIR_PLAY)? &sc->pch : &sc->rch; 517 518 DEB(printf("esschan_init\n")); 519 ch->parent = sc; 520 ch->channel = c; 521 ch->buffer = b; 522 ch->dir = dir; 523 if (sndbuf_alloc(ch->buffer, sc->parent_dmat, sc->bufsz) == -1) 524 return NULL; 525 ch->hwch = 1; 526 if ((dir == PCMDIR_PLAY) && (sc->duplex)) 527 ch->hwch = 2; 528 return ch; 529} 530 531static int 532esschan_setformat(kobj_t obj, void *data, u_int32_t format) 533{ 534 struct ess_chinfo *ch = data; 535 536 ch->fmt = format; 537 return 0; 538} 539 540static int 541esschan_setspeed(kobj_t obj, void *data, u_int32_t speed) 542{ 543 struct ess_chinfo *ch = data; 544 struct ess_info *sc = ch->parent; 545 546 ch->spd = speed; 547 if (sc->newspeed) 548 ess_calcspeed9(&ch->spd); 549 else 550 ess_calcspeed8(&ch->spd); 551 return ch->spd; 552} 553 554static int 555esschan_setblocksize(kobj_t obj, void *data, u_int32_t blocksize) 556{ 557 struct ess_chinfo *ch = data; 558 559 ch->blksz = blocksize; 560 return ch->blksz; 561} 562 563static int 564esschan_trigger(kobj_t obj, void *data, int go) 565{ 566 struct ess_chinfo *ch = data; 567 struct ess_info *sc = ch->parent; 568 569 DEB(printf("esschan_trigger: %d\n",go)); 570 if (go == PCMTRIG_EMLDMAWR || go == PCMTRIG_EMLDMARD) 571 return 0; 572 573 switch (go) { 574 case PCMTRIG_START: 575 ess_dmasetup(sc, ch->hwch, sndbuf_getbufaddr(ch->buffer), sndbuf_getsize(ch->buffer), ch->dir); 576 ess_dmatrigger(sc, ch->hwch, 1); 577 ess_start(ch); 578 break; 579 580 case PCMTRIG_STOP: 581 case PCMTRIG_ABORT: 582 default: 583 ess_stop(ch); 584 break; 585 } 586 return 0; 587} 588 589static int 590esschan_getptr(kobj_t obj, void *data) 591{ 592 struct ess_chinfo *ch = data; 593 struct ess_info *sc = ch->parent; 594 595 return ess_dmapos(sc, ch->hwch); 596} 597 598static struct pcmchan_caps * 599esschan_getcaps(kobj_t obj, void *data) 600{ 601 struct ess_chinfo *ch = data; 602 603 return (ch->dir == PCMDIR_PLAY)? &ess_playcaps : &ess_reccaps; 604} 605 606static kobj_method_t esschan_methods[] = { 607 KOBJMETHOD(channel_init, esschan_init), 608 KOBJMETHOD(channel_setformat, esschan_setformat), 609 KOBJMETHOD(channel_setspeed, esschan_setspeed), 610 KOBJMETHOD(channel_setblocksize, esschan_setblocksize), 611 KOBJMETHOD(channel_trigger, esschan_trigger), 612 KOBJMETHOD(channel_getptr, esschan_getptr), 613 KOBJMETHOD(channel_getcaps, esschan_getcaps), 614 { 0, 0 } 615}; 616CHANNEL_DECLARE(esschan); 617 618/************************************************************/ 619 620static int 621essmix_init(struct snd_mixer *m) 622{ 623 struct ess_info *sc = mix_getdevinfo(m); 624 625 mix_setrecdevs(m, SOUND_MASK_CD | SOUND_MASK_MIC | SOUND_MASK_LINE | 626 SOUND_MASK_IMIX); 627 628 mix_setdevs(m, SOUND_MASK_SYNTH | SOUND_MASK_PCM | SOUND_MASK_LINE | 629 SOUND_MASK_MIC | SOUND_MASK_CD | SOUND_MASK_VOLUME | 630 SOUND_MASK_LINE1); 631 632 ess_setmixer(sc, 0, 0); /* reset */ 633 634 return 0; 635} 636 637static int 638essmix_set(struct snd_mixer *m, unsigned dev, unsigned left, unsigned right) 639{ 640 struct ess_info *sc = mix_getdevinfo(m); 641 int preg = 0, rreg = 0, l, r; 642 643 l = (left * 15) / 100; 644 r = (right * 15) / 100; 645 switch (dev) { 646 case SOUND_MIXER_SYNTH: 647 preg = 0x36; 648 rreg = 0x6b; 649 break; 650 651 case SOUND_MIXER_PCM: 652 preg = 0x14; 653 rreg = 0x7c; 654 break; 655 656 case SOUND_MIXER_LINE: 657 preg = 0x3e; 658 rreg = 0x6e; 659 break; 660 661 case SOUND_MIXER_MIC: 662 preg = 0x1a; 663 rreg = 0x68; 664 break; 665 666 case SOUND_MIXER_LINE1: 667 preg = 0x3a; 668 rreg = 0x6c; 669 break; 670 671 case SOUND_MIXER_CD: 672 preg = 0x38; 673 rreg = 0x6a; 674 break; 675 676 case SOUND_MIXER_VOLUME: 677 l = left? (left * 63) / 100 : 64; 678 r = right? (right * 63) / 100 : 64; 679 ess_setmixer(sc, 0x60, l); 680 ess_setmixer(sc, 0x62, r); 681 left = (l == 64)? 0 : (l * 100) / 63; 682 right = (r == 64)? 0 : (r * 100) / 63; 683 return left | (right << 8); 684 } 685 686 if (preg) 687 ess_setmixer(sc, preg, (l << 4) | r); 688 if (rreg) 689 ess_setmixer(sc, rreg, (l << 4) | r); 690 691 left = (l * 100) / 15; 692 right = (r * 100) / 15; 693 694 return left | (right << 8); 695} 696 697static int 698essmix_setrecsrc(struct snd_mixer *m, u_int32_t src) 699{ 700 struct ess_info *sc = mix_getdevinfo(m); 701 u_char recdev; 702 703 switch (src) { 704 case SOUND_MASK_CD: 705 recdev = 0x02; 706 break; 707 708 case SOUND_MASK_LINE: 709 recdev = 0x06; 710 break; 711 712 case SOUND_MASK_IMIX: 713 recdev = 0x05; 714 break; 715 716 case SOUND_MASK_MIC: 717 default: 718 recdev = 0x00; 719 src = SOUND_MASK_MIC; 720 break; 721 } 722 723 ess_setmixer(sc, 0x1c, recdev); 724 725 return src; 726} 727 728static kobj_method_t solomixer_methods[] = { 729 KOBJMETHOD(mixer_init, essmix_init), 730 KOBJMETHOD(mixer_set, essmix_set), 731 KOBJMETHOD(mixer_setrecsrc, essmix_setrecsrc), 732 { 0, 0 } 733}; 734MIXER_DECLARE(solomixer); 735 736/************************************************************/ 737 738static int 739ess_dmasetup(struct ess_info *sc, int ch, u_int32_t base, u_int16_t cnt, int dir) 740{ 741 KASSERT(ch == 1 || ch == 2, ("bad ch")); 742 sc->dmasz[ch - 1] = cnt; 743 if (ch == 1) { 744 port_wr(sc->vc, 0x8, 0xc4, 1); /* command */ 745 port_wr(sc->vc, 0xd, 0xff, 1); /* reset */ 746 port_wr(sc->vc, 0xf, 0x01, 1); /* mask */ 747 port_wr(sc->vc, 0xb, dir == PCMDIR_PLAY? 0x58 : 0x54, 1); /* mode */ 748 port_wr(sc->vc, 0x0, base, 4); 749 port_wr(sc->vc, 0x4, cnt - 1, 2); 750 751 } else if (ch == 2) { 752 port_wr(sc->io, 0x6, 0x08, 1); /* autoinit */ 753 port_wr(sc->io, 0x0, base, 4); 754 port_wr(sc->io, 0x4, cnt, 2); 755 } 756 return 0; 757} 758 759static int 760ess_dmapos(struct ess_info *sc, int ch) 761{ 762 int p = 0, i = 0, j = 0; 763 u_long flags; 764 765 KASSERT(ch == 1 || ch == 2, ("bad ch")); 766 flags = spltty(); 767 if (ch == 1) { 768 769/* 770 * During recording, this register is known to give back 771 * garbage if it's not quiescent while being read. That's 772 * why we spl, stop the DMA, and try over and over until 773 * adjacent reads are "close", in the right order and not 774 * bigger than is otherwise possible. 775 */ 776 ess_dmatrigger(sc, ch, 0); 777 DELAY(20); 778 do { 779 DELAY(10); 780 if (j > 1) 781 printf("DMA count reg bogus: %04x & %04x\n", 782 i, p); 783 i = port_rd(sc->vc, 0x4, 2) + 1; 784 p = port_rd(sc->vc, 0x4, 2) + 1; 785 } while ((p > sc->dmasz[ch - 1] || i < p || (p - i) > 0x8) && j++ < 1000); 786 ess_dmatrigger(sc, ch, 1); 787 } 788 else if (ch == 2) 789 p = port_rd(sc->io, 0x4, 2); 790 splx(flags); 791 return sc->dmasz[ch - 1] - p; 792} 793 794static int 795ess_dmatrigger(struct ess_info *sc, int ch, int go) 796{ 797 KASSERT(ch == 1 || ch == 2, ("bad ch")); 798 if (ch == 1) 799 port_wr(sc->vc, 0xf, go? 0x00 : 0x01, 1); /* mask */ 800 else if (ch == 2) 801 port_wr(sc->io, 0x6, 0x08 | (go? 0x02 : 0x00), 1); /* autoinit */ 802 return 0; 803} 804 805static void 806ess_release_resources(struct ess_info *sc, device_t dev) 807{ 808 if (sc->irq) { 809 if (sc->ih) 810 bus_teardown_intr(dev, sc->irq, sc->ih); 811 bus_release_resource(dev, SYS_RES_IRQ, 0, sc->irq); 812 sc->irq = 0; 813 } 814 if (sc->io) { 815 bus_release_resource(dev, SYS_RES_IOPORT, PCIR_BAR(0), sc->io); 816 sc->io = 0; 817 } 818 819 if (sc->sb) { 820 bus_release_resource(dev, SYS_RES_IOPORT, PCIR_BAR(1), sc->sb); 821 sc->sb = 0; 822 } 823 824 if (sc->vc) { 825 bus_release_resource(dev, SYS_RES_IOPORT, PCIR_BAR(2), sc->vc); 826 sc->vc = 0; 827 } 828 829 if (sc->mpu) { 830 bus_release_resource(dev, SYS_RES_IOPORT, PCIR_BAR(3), sc->mpu); 831 sc->mpu = 0; 832 } 833 834 if (sc->gp) { 835 bus_release_resource(dev, SYS_RES_IOPORT, PCIR_BAR(4), sc->gp); 836 sc->gp = 0; 837 } 838 839 if (sc->parent_dmat) { 840 bus_dma_tag_destroy(sc->parent_dmat); 841 sc->parent_dmat = 0; 842 } 843 844 free(sc, M_DEVBUF); 845} 846 847static int 848ess_alloc_resources(struct ess_info *sc, device_t dev) 849{ 850 int rid; 851 852 rid = PCIR_BAR(0); 853 sc->io = bus_alloc_resource(dev, SYS_RES_IOPORT, &rid, 0, ~0, 1, RF_ACTIVE); 854 855 rid = PCIR_BAR(1); 856 sc->sb = bus_alloc_resource(dev, SYS_RES_IOPORT, &rid, 0, ~0, 1, RF_ACTIVE); 857 858 rid = PCIR_BAR(2); 859 sc->vc = bus_alloc_resource(dev, SYS_RES_IOPORT, &rid, 0, ~0, 1, RF_ACTIVE); 860 861 rid = PCIR_BAR(3); 862 sc->mpu = bus_alloc_resource(dev, SYS_RES_IOPORT, &rid, 0, ~0, 1, RF_ACTIVE); 863 864 rid = PCIR_BAR(4); 865 sc->gp = bus_alloc_resource(dev, SYS_RES_IOPORT, &rid, 0, ~0, 1, RF_ACTIVE); 866 867 rid = 0; 868 sc->irq = bus_alloc_resource(dev, SYS_RES_IRQ, &rid, 0, ~0, 1, RF_ACTIVE | RF_SHAREABLE); 869 870 return (sc->irq && sc->io && sc->sb && sc->vc && sc->mpu && sc->gp)? 0 : ENXIO; 871} 872 873static int 874ess_probe(device_t dev) 875{ 876 char *s = NULL; 877 u_int32_t subdev; 878 879 subdev = (pci_get_subdevice(dev) << 16) | pci_get_subvendor(dev); 880 switch (pci_get_devid(dev)) { 881 case 0x1969125d: 882 if (subdev == 0x8888125d) 883 s = "ESS Solo-1E"; 884 else if (subdev == 0x1818125d) 885 s = "ESS Solo-1"; 886 else 887 s = "ESS Solo-1 (unknown vendor)"; 888 break; 889 } 890 891 if (s) 892 device_set_desc(dev, s); 893 return s? 0 : ENXIO; 894} 895 896#define ESS_PCI_LEGACYCONTROL 0x40 897#define ESS_PCI_CONFIG 0x50 898#define ESS_PCI_DDMACONTROL 0x60 899 900static int 901ess_suspend(device_t dev) 902{ 903 return 0; 904} 905 906static int 907ess_resume(device_t dev) 908{ 909 uint16_t ddma; 910 uint32_t data; 911 struct ess_info *sc = pcm_getdevinfo(dev); 912 913 data = pci_read_config(dev, PCIR_COMMAND, 2); 914 data |= PCIM_CMD_PORTEN | PCIM_CMD_BUSMASTEREN; 915 pci_write_config(dev, PCIR_COMMAND, data, 2); 916 data = pci_read_config(dev, PCIR_COMMAND, 2); 917 918 ddma = rman_get_start(sc->vc) | 1; 919 pci_write_config(dev, ESS_PCI_LEGACYCONTROL, 0x805f, 2); 920 pci_write_config(dev, ESS_PCI_DDMACONTROL, ddma, 2); 921 pci_write_config(dev, ESS_PCI_CONFIG, 0, 2); 922 923 if (ess_reset_dsp(sc)) 924 goto no; 925 if (mixer_reinit(dev)) 926 goto no; 927 if (sc->newspeed) 928 ess_setmixer(sc, 0x71, 0x2a); 929 930 port_wr(sc->io, 0x7, 0xb0, 1); /* enable irqs */ 931 932 return 0; 933 no: 934 return EIO; 935} 936 937static int 938ess_attach(device_t dev) 939{ 940 struct ess_info *sc; 941 char status[SND_STATUSLEN]; 942 u_int16_t ddma; 943 u_int32_t data; 944 945 sc = (struct ess_info *)malloc(sizeof *sc, M_DEVBUF, M_NOWAIT | M_ZERO); 946 if (!sc) 947 return ENXIO; 948 949 data = pci_read_config(dev, PCIR_COMMAND, 2); 950 data |= PCIM_CMD_PORTEN | PCIM_CMD_BUSMASTEREN; 951 pci_write_config(dev, PCIR_COMMAND, data, 2); 952 data = pci_read_config(dev, PCIR_COMMAND, 2); 953 954 if (ess_alloc_resources(sc, dev)) 955 goto no; 956 957 sc->bufsz = pcm_getbuffersize(dev, 4096, SOLO_DEFAULT_BUFSZ, 65536); 958 959 ddma = rman_get_start(sc->vc) | 1; 960 pci_write_config(dev, ESS_PCI_LEGACYCONTROL, 0x805f, 2); 961 pci_write_config(dev, ESS_PCI_DDMACONTROL, ddma, 2); 962 pci_write_config(dev, ESS_PCI_CONFIG, 0, 2); 963 964 if (ess_reset_dsp(sc)) 965 goto no; 966 if (mixer_init(dev, &solomixer_class, sc)) 967 goto no; 968 969 port_wr(sc->io, 0x7, 0xb0, 1); /* enable irqs */ 970#ifdef ESS18XX_DUPLEX 971 sc->duplex = 1; 972#else 973 sc->duplex = 0; 974#endif 975 976#ifdef ESS18XX_NEWSPEED 977 sc->newspeed = 1; 978#else 979 sc->newspeed = 0; 980#endif 981 if (sc->newspeed) 982 ess_setmixer(sc, 0x71, 0x2a); 983 984 snd_setup_intr(dev, sc->irq, 0, ess_intr, sc, &sc->ih); 985 if (!sc->duplex) 986 pcm_setflags(dev, pcm_getflags(dev) | SD_F_SIMPLEX); 987 988 if (bus_dma_tag_create(/*parent*/NULL, /*alignment*/65536, /*boundary*/0, 989 /*lowaddr*/BUS_SPACE_MAXADDR_24BIT, 990 /*highaddr*/BUS_SPACE_MAXADDR, 991 /*filter*/NULL, /*filterarg*/NULL, 992 /*maxsize*/sc->bufsz, /*nsegments*/1, 993 /*maxsegz*/0x3ffff, 994 /*flags*/0, /*lockfunc*/busdma_lock_mutex, 995 /*lockarg*/&Giant, &sc->parent_dmat) != 0) { 996 device_printf(dev, "unable to create dma tag\n"); 997 goto no; 998 } 999
| 37 38#define SOLO_DEFAULT_BUFSZ 16384 39#define ABS(x) (((x) < 0)? -(x) : (x)) 40 41/* if defined, playback always uses the 2nd channel and full duplex works */ 42#undef ESS18XX_DUPLEX 43 44/* more accurate clocks and split audio1/audio2 rates */ 45#define ESS18XX_NEWSPEED 46 47static u_int32_t ess_playfmt[] = { 48 AFMT_U8, 49 AFMT_STEREO | AFMT_U8, 50 AFMT_S8, 51 AFMT_STEREO | AFMT_S8, 52 AFMT_S16_LE, 53 AFMT_STEREO | AFMT_S16_LE, 54 AFMT_U16_LE, 55 AFMT_STEREO | AFMT_U16_LE, 56 0 57}; 58static struct pcmchan_caps ess_playcaps = {5000, 49000, ess_playfmt, 0}; 59 60/* 61 * Recording output is byte-swapped 62 */ 63static u_int32_t ess_recfmt[] = { 64 AFMT_U8, 65 AFMT_STEREO | AFMT_U8, 66 AFMT_S8, 67 AFMT_STEREO | AFMT_S8, 68 AFMT_S16_BE, 69 AFMT_STEREO | AFMT_S16_BE, 70 AFMT_U16_BE, 71 AFMT_STEREO | AFMT_U16_BE, 72 0 73}; 74static struct pcmchan_caps ess_reccaps = {5000, 49000, ess_recfmt, 0}; 75 76struct ess_info; 77 78struct ess_chinfo { 79 struct ess_info *parent; 80 struct pcm_channel *channel; 81 struct snd_dbuf *buffer; 82 int dir, hwch, stopping; 83 u_int32_t fmt, spd, blksz; 84}; 85 86struct ess_info { 87 struct resource *io, *sb, *vc, *mpu, *gp; /* I/O address for the board */ 88 struct resource *irq; 89 void *ih; 90 bus_dma_tag_t parent_dmat; 91 92 int simplex_dir, type, duplex:1, newspeed:1, dmasz[2]; 93 unsigned int bufsz; 94 95 struct ess_chinfo pch, rch; 96}; 97 98static int ess_rd(struct ess_info *sc, int reg); 99static void ess_wr(struct ess_info *sc, int reg, u_int8_t val); 100static int ess_dspready(struct ess_info *sc); 101static int ess_cmd(struct ess_info *sc, u_char val); 102static int ess_cmd1(struct ess_info *sc, u_char cmd, int val); 103static int ess_get_byte(struct ess_info *sc); 104static void ess_setmixer(struct ess_info *sc, u_int port, u_int value); 105static int ess_getmixer(struct ess_info *sc, u_int port); 106static int ess_reset_dsp(struct ess_info *sc); 107 108static int ess_write(struct ess_info *sc, u_char reg, int val); 109static int ess_read(struct ess_info *sc, u_char reg); 110 111static void ess_intr(void *arg); 112static int ess_setupch(struct ess_info *sc, int ch, int dir, int spd, u_int32_t fmt, int len); 113static int ess_start(struct ess_chinfo *ch); 114static int ess_stop(struct ess_chinfo *ch); 115 116static int ess_dmasetup(struct ess_info *sc, int ch, u_int32_t base, u_int16_t cnt, int dir); 117static int ess_dmapos(struct ess_info *sc, int ch); 118static int ess_dmatrigger(struct ess_info *sc, int ch, int go); 119 120/* 121 * Common code for the midi and pcm functions 122 * 123 * ess_cmd write a single byte to the CMD port. 124 * ess_cmd1 write a CMD + 1 byte arg 125 * ess_cmd2 write a CMD + 2 byte arg 126 * ess_get_byte returns a single byte from the DSP data port 127 * 128 * ess_write is actually ess_cmd1 129 * ess_read access ext. regs via ess_cmd(0xc0, reg) followed by ess_get_byte 130 */ 131 132static int 133port_rd(struct resource *port, int regno, int size) 134{ 135 bus_space_tag_t st = rman_get_bustag(port); 136 bus_space_handle_t sh = rman_get_bushandle(port); 137 138 switch (size) { 139 case 1: 140 return bus_space_read_1(st, sh, regno); 141 case 2: 142 return bus_space_read_2(st, sh, regno); 143 case 4: 144 return bus_space_read_4(st, sh, regno); 145 default: 146 return 0xffffffff; 147 } 148} 149 150static void 151port_wr(struct resource *port, int regno, u_int32_t data, int size) 152{ 153 bus_space_tag_t st = rman_get_bustag(port); 154 bus_space_handle_t sh = rman_get_bushandle(port); 155 156 switch (size) { 157 case 1: 158 bus_space_write_1(st, sh, regno, data); 159 break; 160 case 2: 161 bus_space_write_2(st, sh, regno, data); 162 break; 163 case 4: 164 bus_space_write_4(st, sh, regno, data); 165 break; 166 } 167} 168 169static int 170ess_rd(struct ess_info *sc, int reg) 171{ 172 return port_rd(sc->sb, reg, 1); 173} 174 175static void 176ess_wr(struct ess_info *sc, int reg, u_int8_t val) 177{ 178 port_wr(sc->sb, reg, val, 1); 179} 180 181static int 182ess_dspready(struct ess_info *sc) 183{ 184 return ((ess_rd(sc, SBDSP_STATUS) & 0x80) == 0); 185} 186 187static int 188ess_dspwr(struct ess_info *sc, u_char val) 189{ 190 int i; 191 192 for (i = 0; i < 1000; i++) { 193 if (ess_dspready(sc)) { 194 ess_wr(sc, SBDSP_CMD, val); 195 return 1; 196 } 197 if (i > 10) DELAY((i > 100)? 1000 : 10); 198 } 199 printf("ess_dspwr(0x%02x) timed out.\n", val); 200 return 0; 201} 202 203static int 204ess_cmd(struct ess_info *sc, u_char val) 205{ 206 DEB(printf("ess_cmd: %x\n", val)); 207 return ess_dspwr(sc, val); 208} 209 210static int 211ess_cmd1(struct ess_info *sc, u_char cmd, int val) 212{ 213 DEB(printf("ess_cmd1: %x, %x\n", cmd, val)); 214 if (ess_dspwr(sc, cmd)) { 215 return ess_dspwr(sc, val & 0xff); 216 } else return 0; 217} 218 219static void 220ess_setmixer(struct ess_info *sc, u_int port, u_int value) 221{ 222 u_long flags; 223 224 DEB(printf("ess_setmixer: reg=%x, val=%x\n", port, value);) 225 flags = spltty(); 226 ess_wr(sc, SB_MIX_ADDR, (u_char) (port & 0xff)); /* Select register */ 227 DELAY(10); 228 ess_wr(sc, SB_MIX_DATA, (u_char) (value & 0xff)); 229 DELAY(10); 230 splx(flags); 231} 232 233static int 234ess_getmixer(struct ess_info *sc, u_int port) 235{ 236 int val; 237 u_long flags; 238 239 flags = spltty(); 240 ess_wr(sc, SB_MIX_ADDR, (u_char) (port & 0xff)); /* Select register */ 241 DELAY(10); 242 val = ess_rd(sc, SB_MIX_DATA); 243 DELAY(10); 244 splx(flags); 245 246 return val; 247} 248 249static int 250ess_get_byte(struct ess_info *sc) 251{ 252 int i; 253 254 for (i = 1000; i > 0; i--) { 255 if (ess_rd(sc, 0xc) & 0x40) 256 return ess_rd(sc, DSP_READ); 257 else 258 DELAY(20); 259 } 260 return -1; 261} 262 263static int 264ess_write(struct ess_info *sc, u_char reg, int val) 265{ 266 return ess_cmd1(sc, reg, val); 267} 268 269static int 270ess_read(struct ess_info *sc, u_char reg) 271{ 272 return (ess_cmd(sc, 0xc0) && ess_cmd(sc, reg))? ess_get_byte(sc) : -1; 273} 274 275static int 276ess_reset_dsp(struct ess_info *sc) 277{ 278 DEB(printf("ess_reset_dsp\n")); 279 ess_wr(sc, SBDSP_RST, 3); 280 DELAY(100); 281 ess_wr(sc, SBDSP_RST, 0); 282 if (ess_get_byte(sc) != 0xAA) { 283 DEB(printf("ess_reset_dsp failed\n")); 284/* 285 rman_get_start(d->io_base))); 286*/ 287 return ENXIO; /* Sorry */ 288 } 289 ess_cmd(sc, 0xc6); 290 return 0; 291} 292 293static void 294ess_intr(void *arg) 295{ 296 struct ess_info *sc = (struct ess_info *)arg; 297 int src, pirq = 0, rirq = 0; 298 299 src = 0; 300 if (ess_getmixer(sc, 0x7a) & 0x80) 301 src |= 2; 302 if (ess_rd(sc, 0x0c) & 0x01) 303 src |= 1; 304 305 if (src == 0) 306 return; 307 308 if (sc->duplex) { 309 pirq = (src & sc->pch.hwch)? 1 : 0; 310 rirq = (src & sc->rch.hwch)? 1 : 0; 311 } else { 312 if (sc->simplex_dir == PCMDIR_PLAY) 313 pirq = 1; 314 if (sc->simplex_dir == PCMDIR_REC) 315 rirq = 1; 316 if (!pirq && !rirq) 317 printf("solo: IRQ neither playback nor rec!\n"); 318 } 319 320 DEB(printf("ess_intr: pirq:%d rirq:%d\n",pirq,rirq)); 321 322 if (pirq) { 323 if (sc->pch.stopping) { 324 ess_dmatrigger(sc, sc->pch.hwch, 0); 325 sc->pch.stopping = 0; 326 if (sc->pch.hwch == 1) 327 ess_write(sc, 0xb8, ess_read(sc, 0xb8) & ~0x01); 328 else 329 ess_setmixer(sc, 0x78, ess_getmixer(sc, 0x78) & ~0x03); 330 } 331 chn_intr(sc->pch.channel); 332 } 333 334 if (rirq) { 335 if (sc->rch.stopping) { 336 ess_dmatrigger(sc, sc->rch.hwch, 0); 337 sc->rch.stopping = 0; 338 /* XXX: will this stop audio2? */ 339 ess_write(sc, 0xb8, ess_read(sc, 0xb8) & ~0x01); 340 } 341 chn_intr(sc->rch.channel); 342 } 343 344 if (src & 2) 345 ess_setmixer(sc, 0x7a, ess_getmixer(sc, 0x7a) & ~0x80); 346 if (src & 1) 347 ess_rd(sc, DSP_DATA_AVAIL); 348} 349 350/* utility functions for ESS */ 351static u_int8_t 352ess_calcspeed8(int *spd) 353{ 354 int speed = *spd; 355 u_int32_t t; 356 357 if (speed > 22000) { 358 t = (795500 + speed / 2) / speed; 359 speed = (795500 + t / 2) / t; 360 t = (256 - t) | 0x80; 361 } else { 362 t = (397700 + speed / 2) / speed; 363 speed = (397700 + t / 2) / t; 364 t = 128 - t; 365 } 366 *spd = speed; 367 return t & 0x000000ff; 368} 369 370static u_int8_t 371ess_calcspeed9(int *spd) 372{ 373 int speed, s0, s1, use0; 374 u_int8_t t0, t1; 375 376 /* rate = source / (256 - divisor) */ 377 /* divisor = 256 - (source / rate) */ 378 speed = *spd; 379 t0 = 128 - (793800 / speed); 380 s0 = 793800 / (128 - t0); 381 382 t1 = 128 - (768000 / speed); 383 s1 = 768000 / (128 - t1); 384 t1 |= 0x80; 385 386 use0 = (ABS(speed - s0) < ABS(speed - s1))? 1 : 0; 387 388 *spd = use0? s0 : s1; 389 return use0? t0 : t1; 390} 391 392static u_int8_t 393ess_calcfilter(int spd) 394{ 395 int cutoff; 396 397 /* cutoff = 7160000 / (256 - divisor) */ 398 /* divisor = 256 - (7160000 / cutoff) */ 399 cutoff = (spd * 9 * 82) / 20; 400 return (256 - (7160000 / cutoff)); 401} 402 403static int 404ess_setupch(struct ess_info *sc, int ch, int dir, int spd, u_int32_t fmt, int len) 405{ 406 int play = (dir == PCMDIR_PLAY)? 1 : 0; 407 int b16 = (fmt & AFMT_16BIT)? 1 : 0; 408 int stereo = (fmt & AFMT_STEREO)? 1 : 0; 409 int unsign = (fmt == AFMT_U8 || fmt == AFMT_U16_LE || fmt == AFMT_U16_BE)? 1 : 0; 410 u_int8_t spdval, fmtval; 411 412 DEB(printf("ess_setupch\n")); 413 spdval = (sc->newspeed)? ess_calcspeed9(&spd) : ess_calcspeed8(&spd); 414 415 sc->simplex_dir = play ? PCMDIR_PLAY : PCMDIR_REC ; 416 417 if (ch == 1) { 418 KASSERT((dir == PCMDIR_PLAY) || (dir == PCMDIR_REC), ("ess_setupch: dir1 bad")); 419 len = -len; 420 /* transfer length low */ 421 ess_write(sc, 0xa4, len & 0x00ff); 422 /* transfer length high */ 423 ess_write(sc, 0xa5, (len & 0xff00) >> 8); 424 /* autoinit, dma dir */ 425 ess_write(sc, 0xb8, 0x04 | (play? 0x00 : 0x0a)); 426 /* mono/stereo */ 427 ess_write(sc, 0xa8, (ess_read(sc, 0xa8) & ~0x03) | (stereo? 0x01 : 0x02)); 428 /* demand mode, 4 bytes/xfer */ 429 ess_write(sc, 0xb9, 0x02); 430 /* sample rate */ 431 ess_write(sc, 0xa1, spdval); 432 /* filter cutoff */ 433 ess_write(sc, 0xa2, ess_calcfilter(spd)); 434 /* setup dac/adc */ 435 /* 436 if (play) 437 ess_write(sc, 0xb6, unsign? 0x80 : 0x00); 438 */ 439 /* mono, b16: signed, load signal */ 440 /* 441 ess_write(sc, 0xb7, 0x51 | (unsign? 0x00 : 0x20)); 442 */ 443 /* setup fifo */ 444 ess_write(sc, 0xb7, 0x91 | (unsign? 0x00 : 0x20) | 445 (b16? 0x04 : 0x00) | 446 (stereo? 0x08 : 0x40)); 447 /* irq control */ 448 ess_write(sc, 0xb1, (ess_read(sc, 0xb1) & 0x0f) | 0x50); 449 /* drq control */ 450 ess_write(sc, 0xb2, (ess_read(sc, 0xb2) & 0x0f) | 0x50); 451 } else if (ch == 2) { 452 KASSERT(dir == PCMDIR_PLAY, ("ess_setupch: dir2 bad")); 453 len >>= 1; 454 len = -len; 455 /* transfer length low */ 456 ess_setmixer(sc, 0x74, len & 0x00ff); 457 /* transfer length high */ 458 ess_setmixer(sc, 0x76, (len & 0xff00) >> 8); 459 /* autoinit, 4 bytes/req */ 460 ess_setmixer(sc, 0x78, 0x10); 461 fmtval = b16 | (stereo << 1) | ((!unsign) << 2); 462 /* enable irq, set format */ 463 ess_setmixer(sc, 0x7a, 0x40 | fmtval); 464 if (sc->newspeed) { 465 /* sample rate */ 466 ess_setmixer(sc, 0x70, spdval); 467 /* filter cutoff */ 468 ess_setmixer(sc, 0x72, ess_calcfilter(spd)); 469 } 470 471 } 472 return 0; 473} 474static int 475ess_start(struct ess_chinfo *ch) 476{ 477 struct ess_info *sc = ch->parent; 478 479 DEB(printf("ess_start\n");); 480 ess_setupch(sc, ch->hwch, ch->dir, ch->spd, ch->fmt, ch->blksz); 481 ch->stopping = 0; 482 if (ch->hwch == 1) { 483 ess_write(sc, 0xb8, ess_read(sc, 0xb8) | 0x01); 484 if (ch->dir == PCMDIR_PLAY) { 485#if 0 486 DELAY(100000); /* 100 ms */ 487#endif 488 ess_cmd(sc, 0xd1); 489 } 490 } else 491 ess_setmixer(sc, 0x78, ess_getmixer(sc, 0x78) | 0x03); 492 return 0; 493} 494 495static int 496ess_stop(struct ess_chinfo *ch) 497{ 498 struct ess_info *sc = ch->parent; 499 500 DEB(printf("ess_stop\n")); 501 ch->stopping = 1; 502 if (ch->hwch == 1) 503 ess_write(sc, 0xb8, ess_read(sc, 0xb8) & ~0x04); 504 else 505 ess_setmixer(sc, 0x78, ess_getmixer(sc, 0x78) & ~0x10); 506 DEB(printf("done with stop\n")); 507 return 0; 508} 509 510/* -------------------------------------------------------------------- */ 511/* channel interface for ESS18xx */ 512static void * 513esschan_init(kobj_t obj, void *devinfo, struct snd_dbuf *b, struct pcm_channel *c, int dir) 514{ 515 struct ess_info *sc = devinfo; 516 struct ess_chinfo *ch = (dir == PCMDIR_PLAY)? &sc->pch : &sc->rch; 517 518 DEB(printf("esschan_init\n")); 519 ch->parent = sc; 520 ch->channel = c; 521 ch->buffer = b; 522 ch->dir = dir; 523 if (sndbuf_alloc(ch->buffer, sc->parent_dmat, sc->bufsz) == -1) 524 return NULL; 525 ch->hwch = 1; 526 if ((dir == PCMDIR_PLAY) && (sc->duplex)) 527 ch->hwch = 2; 528 return ch; 529} 530 531static int 532esschan_setformat(kobj_t obj, void *data, u_int32_t format) 533{ 534 struct ess_chinfo *ch = data; 535 536 ch->fmt = format; 537 return 0; 538} 539 540static int 541esschan_setspeed(kobj_t obj, void *data, u_int32_t speed) 542{ 543 struct ess_chinfo *ch = data; 544 struct ess_info *sc = ch->parent; 545 546 ch->spd = speed; 547 if (sc->newspeed) 548 ess_calcspeed9(&ch->spd); 549 else 550 ess_calcspeed8(&ch->spd); 551 return ch->spd; 552} 553 554static int 555esschan_setblocksize(kobj_t obj, void *data, u_int32_t blocksize) 556{ 557 struct ess_chinfo *ch = data; 558 559 ch->blksz = blocksize; 560 return ch->blksz; 561} 562 563static int 564esschan_trigger(kobj_t obj, void *data, int go) 565{ 566 struct ess_chinfo *ch = data; 567 struct ess_info *sc = ch->parent; 568 569 DEB(printf("esschan_trigger: %d\n",go)); 570 if (go == PCMTRIG_EMLDMAWR || go == PCMTRIG_EMLDMARD) 571 return 0; 572 573 switch (go) { 574 case PCMTRIG_START: 575 ess_dmasetup(sc, ch->hwch, sndbuf_getbufaddr(ch->buffer), sndbuf_getsize(ch->buffer), ch->dir); 576 ess_dmatrigger(sc, ch->hwch, 1); 577 ess_start(ch); 578 break; 579 580 case PCMTRIG_STOP: 581 case PCMTRIG_ABORT: 582 default: 583 ess_stop(ch); 584 break; 585 } 586 return 0; 587} 588 589static int 590esschan_getptr(kobj_t obj, void *data) 591{ 592 struct ess_chinfo *ch = data; 593 struct ess_info *sc = ch->parent; 594 595 return ess_dmapos(sc, ch->hwch); 596} 597 598static struct pcmchan_caps * 599esschan_getcaps(kobj_t obj, void *data) 600{ 601 struct ess_chinfo *ch = data; 602 603 return (ch->dir == PCMDIR_PLAY)? &ess_playcaps : &ess_reccaps; 604} 605 606static kobj_method_t esschan_methods[] = { 607 KOBJMETHOD(channel_init, esschan_init), 608 KOBJMETHOD(channel_setformat, esschan_setformat), 609 KOBJMETHOD(channel_setspeed, esschan_setspeed), 610 KOBJMETHOD(channel_setblocksize, esschan_setblocksize), 611 KOBJMETHOD(channel_trigger, esschan_trigger), 612 KOBJMETHOD(channel_getptr, esschan_getptr), 613 KOBJMETHOD(channel_getcaps, esschan_getcaps), 614 { 0, 0 } 615}; 616CHANNEL_DECLARE(esschan); 617 618/************************************************************/ 619 620static int 621essmix_init(struct snd_mixer *m) 622{ 623 struct ess_info *sc = mix_getdevinfo(m); 624 625 mix_setrecdevs(m, SOUND_MASK_CD | SOUND_MASK_MIC | SOUND_MASK_LINE | 626 SOUND_MASK_IMIX); 627 628 mix_setdevs(m, SOUND_MASK_SYNTH | SOUND_MASK_PCM | SOUND_MASK_LINE | 629 SOUND_MASK_MIC | SOUND_MASK_CD | SOUND_MASK_VOLUME | 630 SOUND_MASK_LINE1); 631 632 ess_setmixer(sc, 0, 0); /* reset */ 633 634 return 0; 635} 636 637static int 638essmix_set(struct snd_mixer *m, unsigned dev, unsigned left, unsigned right) 639{ 640 struct ess_info *sc = mix_getdevinfo(m); 641 int preg = 0, rreg = 0, l, r; 642 643 l = (left * 15) / 100; 644 r = (right * 15) / 100; 645 switch (dev) { 646 case SOUND_MIXER_SYNTH: 647 preg = 0x36; 648 rreg = 0x6b; 649 break; 650 651 case SOUND_MIXER_PCM: 652 preg = 0x14; 653 rreg = 0x7c; 654 break; 655 656 case SOUND_MIXER_LINE: 657 preg = 0x3e; 658 rreg = 0x6e; 659 break; 660 661 case SOUND_MIXER_MIC: 662 preg = 0x1a; 663 rreg = 0x68; 664 break; 665 666 case SOUND_MIXER_LINE1: 667 preg = 0x3a; 668 rreg = 0x6c; 669 break; 670 671 case SOUND_MIXER_CD: 672 preg = 0x38; 673 rreg = 0x6a; 674 break; 675 676 case SOUND_MIXER_VOLUME: 677 l = left? (left * 63) / 100 : 64; 678 r = right? (right * 63) / 100 : 64; 679 ess_setmixer(sc, 0x60, l); 680 ess_setmixer(sc, 0x62, r); 681 left = (l == 64)? 0 : (l * 100) / 63; 682 right = (r == 64)? 0 : (r * 100) / 63; 683 return left | (right << 8); 684 } 685 686 if (preg) 687 ess_setmixer(sc, preg, (l << 4) | r); 688 if (rreg) 689 ess_setmixer(sc, rreg, (l << 4) | r); 690 691 left = (l * 100) / 15; 692 right = (r * 100) / 15; 693 694 return left | (right << 8); 695} 696 697static int 698essmix_setrecsrc(struct snd_mixer *m, u_int32_t src) 699{ 700 struct ess_info *sc = mix_getdevinfo(m); 701 u_char recdev; 702 703 switch (src) { 704 case SOUND_MASK_CD: 705 recdev = 0x02; 706 break; 707 708 case SOUND_MASK_LINE: 709 recdev = 0x06; 710 break; 711 712 case SOUND_MASK_IMIX: 713 recdev = 0x05; 714 break; 715 716 case SOUND_MASK_MIC: 717 default: 718 recdev = 0x00; 719 src = SOUND_MASK_MIC; 720 break; 721 } 722 723 ess_setmixer(sc, 0x1c, recdev); 724 725 return src; 726} 727 728static kobj_method_t solomixer_methods[] = { 729 KOBJMETHOD(mixer_init, essmix_init), 730 KOBJMETHOD(mixer_set, essmix_set), 731 KOBJMETHOD(mixer_setrecsrc, essmix_setrecsrc), 732 { 0, 0 } 733}; 734MIXER_DECLARE(solomixer); 735 736/************************************************************/ 737 738static int 739ess_dmasetup(struct ess_info *sc, int ch, u_int32_t base, u_int16_t cnt, int dir) 740{ 741 KASSERT(ch == 1 || ch == 2, ("bad ch")); 742 sc->dmasz[ch - 1] = cnt; 743 if (ch == 1) { 744 port_wr(sc->vc, 0x8, 0xc4, 1); /* command */ 745 port_wr(sc->vc, 0xd, 0xff, 1); /* reset */ 746 port_wr(sc->vc, 0xf, 0x01, 1); /* mask */ 747 port_wr(sc->vc, 0xb, dir == PCMDIR_PLAY? 0x58 : 0x54, 1); /* mode */ 748 port_wr(sc->vc, 0x0, base, 4); 749 port_wr(sc->vc, 0x4, cnt - 1, 2); 750 751 } else if (ch == 2) { 752 port_wr(sc->io, 0x6, 0x08, 1); /* autoinit */ 753 port_wr(sc->io, 0x0, base, 4); 754 port_wr(sc->io, 0x4, cnt, 2); 755 } 756 return 0; 757} 758 759static int 760ess_dmapos(struct ess_info *sc, int ch) 761{ 762 int p = 0, i = 0, j = 0; 763 u_long flags; 764 765 KASSERT(ch == 1 || ch == 2, ("bad ch")); 766 flags = spltty(); 767 if (ch == 1) { 768 769/* 770 * During recording, this register is known to give back 771 * garbage if it's not quiescent while being read. That's 772 * why we spl, stop the DMA, and try over and over until 773 * adjacent reads are "close", in the right order and not 774 * bigger than is otherwise possible. 775 */ 776 ess_dmatrigger(sc, ch, 0); 777 DELAY(20); 778 do { 779 DELAY(10); 780 if (j > 1) 781 printf("DMA count reg bogus: %04x & %04x\n", 782 i, p); 783 i = port_rd(sc->vc, 0x4, 2) + 1; 784 p = port_rd(sc->vc, 0x4, 2) + 1; 785 } while ((p > sc->dmasz[ch - 1] || i < p || (p - i) > 0x8) && j++ < 1000); 786 ess_dmatrigger(sc, ch, 1); 787 } 788 else if (ch == 2) 789 p = port_rd(sc->io, 0x4, 2); 790 splx(flags); 791 return sc->dmasz[ch - 1] - p; 792} 793 794static int 795ess_dmatrigger(struct ess_info *sc, int ch, int go) 796{ 797 KASSERT(ch == 1 || ch == 2, ("bad ch")); 798 if (ch == 1) 799 port_wr(sc->vc, 0xf, go? 0x00 : 0x01, 1); /* mask */ 800 else if (ch == 2) 801 port_wr(sc->io, 0x6, 0x08 | (go? 0x02 : 0x00), 1); /* autoinit */ 802 return 0; 803} 804 805static void 806ess_release_resources(struct ess_info *sc, device_t dev) 807{ 808 if (sc->irq) { 809 if (sc->ih) 810 bus_teardown_intr(dev, sc->irq, sc->ih); 811 bus_release_resource(dev, SYS_RES_IRQ, 0, sc->irq); 812 sc->irq = 0; 813 } 814 if (sc->io) { 815 bus_release_resource(dev, SYS_RES_IOPORT, PCIR_BAR(0), sc->io); 816 sc->io = 0; 817 } 818 819 if (sc->sb) { 820 bus_release_resource(dev, SYS_RES_IOPORT, PCIR_BAR(1), sc->sb); 821 sc->sb = 0; 822 } 823 824 if (sc->vc) { 825 bus_release_resource(dev, SYS_RES_IOPORT, PCIR_BAR(2), sc->vc); 826 sc->vc = 0; 827 } 828 829 if (sc->mpu) { 830 bus_release_resource(dev, SYS_RES_IOPORT, PCIR_BAR(3), sc->mpu); 831 sc->mpu = 0; 832 } 833 834 if (sc->gp) { 835 bus_release_resource(dev, SYS_RES_IOPORT, PCIR_BAR(4), sc->gp); 836 sc->gp = 0; 837 } 838 839 if (sc->parent_dmat) { 840 bus_dma_tag_destroy(sc->parent_dmat); 841 sc->parent_dmat = 0; 842 } 843 844 free(sc, M_DEVBUF); 845} 846 847static int 848ess_alloc_resources(struct ess_info *sc, device_t dev) 849{ 850 int rid; 851 852 rid = PCIR_BAR(0); 853 sc->io = bus_alloc_resource(dev, SYS_RES_IOPORT, &rid, 0, ~0, 1, RF_ACTIVE); 854 855 rid = PCIR_BAR(1); 856 sc->sb = bus_alloc_resource(dev, SYS_RES_IOPORT, &rid, 0, ~0, 1, RF_ACTIVE); 857 858 rid = PCIR_BAR(2); 859 sc->vc = bus_alloc_resource(dev, SYS_RES_IOPORT, &rid, 0, ~0, 1, RF_ACTIVE); 860 861 rid = PCIR_BAR(3); 862 sc->mpu = bus_alloc_resource(dev, SYS_RES_IOPORT, &rid, 0, ~0, 1, RF_ACTIVE); 863 864 rid = PCIR_BAR(4); 865 sc->gp = bus_alloc_resource(dev, SYS_RES_IOPORT, &rid, 0, ~0, 1, RF_ACTIVE); 866 867 rid = 0; 868 sc->irq = bus_alloc_resource(dev, SYS_RES_IRQ, &rid, 0, ~0, 1, RF_ACTIVE | RF_SHAREABLE); 869 870 return (sc->irq && sc->io && sc->sb && sc->vc && sc->mpu && sc->gp)? 0 : ENXIO; 871} 872 873static int 874ess_probe(device_t dev) 875{ 876 char *s = NULL; 877 u_int32_t subdev; 878 879 subdev = (pci_get_subdevice(dev) << 16) | pci_get_subvendor(dev); 880 switch (pci_get_devid(dev)) { 881 case 0x1969125d: 882 if (subdev == 0x8888125d) 883 s = "ESS Solo-1E"; 884 else if (subdev == 0x1818125d) 885 s = "ESS Solo-1"; 886 else 887 s = "ESS Solo-1 (unknown vendor)"; 888 break; 889 } 890 891 if (s) 892 device_set_desc(dev, s); 893 return s? 0 : ENXIO; 894} 895 896#define ESS_PCI_LEGACYCONTROL 0x40 897#define ESS_PCI_CONFIG 0x50 898#define ESS_PCI_DDMACONTROL 0x60 899 900static int 901ess_suspend(device_t dev) 902{ 903 return 0; 904} 905 906static int 907ess_resume(device_t dev) 908{ 909 uint16_t ddma; 910 uint32_t data; 911 struct ess_info *sc = pcm_getdevinfo(dev); 912 913 data = pci_read_config(dev, PCIR_COMMAND, 2); 914 data |= PCIM_CMD_PORTEN | PCIM_CMD_BUSMASTEREN; 915 pci_write_config(dev, PCIR_COMMAND, data, 2); 916 data = pci_read_config(dev, PCIR_COMMAND, 2); 917 918 ddma = rman_get_start(sc->vc) | 1; 919 pci_write_config(dev, ESS_PCI_LEGACYCONTROL, 0x805f, 2); 920 pci_write_config(dev, ESS_PCI_DDMACONTROL, ddma, 2); 921 pci_write_config(dev, ESS_PCI_CONFIG, 0, 2); 922 923 if (ess_reset_dsp(sc)) 924 goto no; 925 if (mixer_reinit(dev)) 926 goto no; 927 if (sc->newspeed) 928 ess_setmixer(sc, 0x71, 0x2a); 929 930 port_wr(sc->io, 0x7, 0xb0, 1); /* enable irqs */ 931 932 return 0; 933 no: 934 return EIO; 935} 936 937static int 938ess_attach(device_t dev) 939{ 940 struct ess_info *sc; 941 char status[SND_STATUSLEN]; 942 u_int16_t ddma; 943 u_int32_t data; 944 945 sc = (struct ess_info *)malloc(sizeof *sc, M_DEVBUF, M_NOWAIT | M_ZERO); 946 if (!sc) 947 return ENXIO; 948 949 data = pci_read_config(dev, PCIR_COMMAND, 2); 950 data |= PCIM_CMD_PORTEN | PCIM_CMD_BUSMASTEREN; 951 pci_write_config(dev, PCIR_COMMAND, data, 2); 952 data = pci_read_config(dev, PCIR_COMMAND, 2); 953 954 if (ess_alloc_resources(sc, dev)) 955 goto no; 956 957 sc->bufsz = pcm_getbuffersize(dev, 4096, SOLO_DEFAULT_BUFSZ, 65536); 958 959 ddma = rman_get_start(sc->vc) | 1; 960 pci_write_config(dev, ESS_PCI_LEGACYCONTROL, 0x805f, 2); 961 pci_write_config(dev, ESS_PCI_DDMACONTROL, ddma, 2); 962 pci_write_config(dev, ESS_PCI_CONFIG, 0, 2); 963 964 if (ess_reset_dsp(sc)) 965 goto no; 966 if (mixer_init(dev, &solomixer_class, sc)) 967 goto no; 968 969 port_wr(sc->io, 0x7, 0xb0, 1); /* enable irqs */ 970#ifdef ESS18XX_DUPLEX 971 sc->duplex = 1; 972#else 973 sc->duplex = 0; 974#endif 975 976#ifdef ESS18XX_NEWSPEED 977 sc->newspeed = 1; 978#else 979 sc->newspeed = 0; 980#endif 981 if (sc->newspeed) 982 ess_setmixer(sc, 0x71, 0x2a); 983 984 snd_setup_intr(dev, sc->irq, 0, ess_intr, sc, &sc->ih); 985 if (!sc->duplex) 986 pcm_setflags(dev, pcm_getflags(dev) | SD_F_SIMPLEX); 987 988 if (bus_dma_tag_create(/*parent*/NULL, /*alignment*/65536, /*boundary*/0, 989 /*lowaddr*/BUS_SPACE_MAXADDR_24BIT, 990 /*highaddr*/BUS_SPACE_MAXADDR, 991 /*filter*/NULL, /*filterarg*/NULL, 992 /*maxsize*/sc->bufsz, /*nsegments*/1, 993 /*maxsegz*/0x3ffff, 994 /*flags*/0, /*lockfunc*/busdma_lock_mutex, 995 /*lockarg*/&Giant, &sc->parent_dmat) != 0) { 996 device_printf(dev, "unable to create dma tag\n"); 997 goto no; 998 } 999
|