sb16.c revision 57209
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. 9 * 10 * Redistribution and use in source and binary forms, with or without 11 * modification, are permitted provided that the following conditions 12 * are met: 13 * 1. Redistributions of source code must retain the above copyright 14 * notice, this list of conditions and the following disclaimer. 15 * 2. Redistributions in binary form must reproduce the above copyright 16 * notice, this list of conditions and the following disclaimer in the 17 * documentation and/or other materials provided with the distribution. 18 * 19 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 20 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 21 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 22 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 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 57209 2000-02-14 23:37:02Z 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 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 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, 73 AFMT_U8, 74 AFMT_U8 75}; 76 77static pcmchan_caps sbpro_playcaps = { 78 4000, 45000, 79 AFMT_STEREO | AFMT_U8, 80 AFMT_STEREO | AFMT_U8 81}; 82 83static pcmchan_caps sbpro_reccaps = { 84 4000, 15000, 85 AFMT_STEREO | AFMT_U8, 86 AFMT_STEREO | AFMT_U8 87}; 88 89static pcmchan_caps sb16_hcaps = { 90 5000, 45000, 91 AFMT_STEREO | AFMT_S16_LE, 92 AFMT_STEREO | AFMT_S16_LE 93}; 94 95static pcmchan_caps sb16_lcaps = { 96 5000, 45000, 97 AFMT_STEREO | AFMT_U8, 98 AFMT_STEREO | AFMT_U8 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 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 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; 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; 158 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); 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); 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 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, 197 sbmix_setrecsrc, 198}; 199 200static devclass_t pcm_devclass; 201 202/* 203 * Common code for the midi and pcm functions 204 * 205 * sb_cmd write a single byte to the CMD port. 206 * sb_cmd1 write a CMD + 1 byte arg 207 * sb_cmd2 write a CMD + 2 byte arg 208 * sb_get_byte returns a single byte from the DSP data port 209 * 210 * ess_write is actually sb_cmd1 211 * ess_read access ext. regs via sb_cmd(0xc0, reg) followed by sb_get_byte 212 */ 213 214static int 215port_rd(struct resource *port, int off) 216{ 217 return bus_space_read_1(rman_get_bustag(port), 218 rman_get_bushandle(port), 219 off); 220} 221 222static void 223port_wr(struct resource *port, int off, u_int8_t data) 224{ 225 return bus_space_write_1(rman_get_bustag(port), 226 rman_get_bushandle(port), 227 off, data); 228} 229 230static int 231sb_rd(struct sb_info *sb, int reg) 232{ 233 return port_rd(sb->io_base, reg); 234} 235 236static void 237sb_wr(struct sb_info *sb, int reg, u_int8_t val) 238{ 239 port_wr(sb->io_base, reg, val); 240} 241 242static int 243sb_dspready(struct sb_info *sb) 244{ 245 return ((sb_rd(sb, SBDSP_STATUS) & 0x80) == 0); 246} 247 248static int 249sb_dspwr(struct sb_info *sb, u_char val) 250{ 251 int i; 252 253 for (i = 0; i < 1000; i++) { 254 if (sb_dspready(sb)) { 255 sb_wr(sb, SBDSP_CMD, val); 256 return 1; 257 } 258 if (i > 10) DELAY((i > 100)? 1000 : 10); 259 } 260 printf("sb_dspwr(0x%02x) timed out.\n", val); 261 return 0; 262} 263 264static int 265sb_cmd(struct sb_info *sb, u_char val) 266{ 267#if 0 268 printf("sb_cmd: %x\n", val); 269#endif 270 return sb_dspwr(sb, val); 271} 272 273static int 274sb_cmd1(struct sb_info *sb, u_char cmd, int val) 275{ 276#if 0 277 printf("sb_cmd1: %x, %x\n", cmd, val); 278#endif 279 if (sb_dspwr(sb, cmd)) { 280 return sb_dspwr(sb, val & 0xff); 281 } else return 0; 282} 283 284static int 285sb_cmd2(struct sb_info *sb, u_char cmd, int val) 286{ 287#if 0 288 printf("sb_cmd2: %x, %x\n", cmd, val); 289#endif 290 if (sb_dspwr(sb, cmd)) { 291 return sb_dspwr(sb, val & 0xff) && 292 sb_dspwr(sb, (val >> 8) & 0xff); 293 } else return 0; 294} 295 296/* 297 * in the SB, there is a set of indirect "mixer" registers with 298 * address at offset 4, data at offset 5 299 */ 300static void 301sb_setmixer(struct sb_info *sb, u_int port, u_int value) 302{ 303 u_long flags; 304 305 flags = spltty(); 306 sb_wr(sb, SB_MIX_ADDR, (u_char) (port & 0xff)); /* Select register */ 307 DELAY(10); 308 sb_wr(sb, SB_MIX_DATA, (u_char) (value & 0xff)); 309 DELAY(10); 310 splx(flags); 311} 312 313static int 314sb_getmixer(struct sb_info *sb, u_int port) 315{ 316 int val; 317 u_long flags; 318 319 flags = spltty(); 320 sb_wr(sb, SB_MIX_ADDR, (u_char) (port & 0xff)); /* Select register */ 321 DELAY(10); 322 val = sb_rd(sb, SB_MIX_DATA); 323 DELAY(10); 324 splx(flags); 325 326 return val; 327} 328 329static u_int 330sb_get_byte(struct sb_info *sb) 331{ 332 int i; 333 334 for (i = 1000; i > 0; i--) { 335 if (sb_rd(sb, DSP_DATA_AVAIL) & 0x80) 336 return sb_rd(sb, DSP_READ); 337 else 338 DELAY(20); 339 } 340 return 0xffff; 341} 342 343static 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))); 364 return ENXIO; /* Sorry */ 365 } 366 if (sb->bd_flags & BD_F_ESS) 367 sb_cmd(sb, 0xc6); 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) { 376 bus_release_resource(dev, SYS_RES_IRQ, 0, sb->irq); 377 sb->irq = 0; 378 } 379 if (sb->drq1) { 380 bus_release_resource(dev, SYS_RES_DRQ, 0, sb->drq1); 381 sb->drq1 = 0; 382 } 383 if (sb->drq2) { 384 bus_release_resource(dev, SYS_RES_DRQ, 1, sb->drq2); 385 sb->drq2 = 0; 386 } 387 if (sb->io_base) { 388 bus_release_resource(dev, SYS_RES_IOPORT, 0, sb->io_base); 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; 400 if (!sb->io_base) 401 sb->io_base = bus_alloc_resource(dev, SYS_RES_IOPORT, 402 &rid, 0, ~0, 1, 403 RF_ACTIVE); 404 rid = 0; 405 if (!sb->irq) 406 sb->irq = bus_alloc_resource(dev, SYS_RES_IRQ, 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; 415 if (!sb->drq2 && !(sb->bd_flags & BD_F_ESS)) 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) { 421 int bs = (sb->bd_flags & BD_F_ESS)? ESS_BUFFSIZE : 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 } 430 431 return 0; 432 } else return ENXIO; 433} 434 435static void 436sb16_swap(void *v, int dir) 437{ 438 struct sb_info *sb = v; 439 int pb = sb->pch.buffer->dl; 440 int rb = sb->rch.buffer->dl; 441 int pc = sb->pch.buffer->chan; 442 int rc = sb->rch.buffer->chan; 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; 451 if (sb->bd_flags & BD_F_SB16X) 452 swp = !swp; 453 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 = B_WRITE; 460 sb->rch.buffer->dir = B_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]; 471 int bs = (sb->bd_flags & BD_F_ESS)? ESS_BUFFSIZE : 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 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); 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, 491 /*filter*/NULL, /*filterarg*/NULL, 492 /*maxsize*/bs, /*nsegments*/1, 493 /*maxsegz*/0x3ffff, 494 /*flags*/0, &sb->parent_dmat) != 0) { 495 device_printf(dev, "unable to create dma tag\n"); 496 goto no; 497 } 498 499 snprintf(status, SND_STATUSLEN, "at io 0x%lx irq %ld drq %ld", 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; 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 } 515 pcm_setstatus(dev, status); 516 517 return 0; 518 519no: 520 sb_release_resources(sb, dev); 521 return ENXIO; 522} 523 524static void 525sb_intr(void *arg) 526{ 527 struct sb_info *sb = (struct sb_info *)arg; 528 int reason = 3, c; 529 530 /* 531 * SB < 4.0 is half duplex and has only 1 bit for int source, 532 * so we fake it. SB 4.x (SB16) has the int source in a separate 533 * register. 534 * The Vibra16X has separate flags for 8 and 16 bit transfers, but 535 * I have no idea how to tell capture from playback interrupts... 536 */ 537 if (sb->bd_flags & BD_F_SB16) { 538 c = sb_getmixer(sb, IRQ_STAT); 539 /* this tells us if the source is 8-bit or 16-bit dma. We 540 * have to check the io channel to map it to read or write... 541 */ 542 reason = 0; 543 if (c & 1) { /* 8-bit dma */ 544 if (sb->pch.fmt & AFMT_U8) 545 reason |= 1; 546 if (sb->rch.fmt & AFMT_U8) 547 reason |= 2; 548 } 549 if (c & 2) { /* 16-bit dma */ 550 if (sb->pch.fmt & AFMT_S16_LE) 551 reason |= 1; 552 if (sb->rch.fmt & AFMT_S16_LE) 553 reason |= 2; 554 } 555 } else c = 1; 556#if 0 557 printf("sb_intr: reason=%d c=0x%x\n", reason, c); 558#endif 559 if ((reason & 1) && (sb->pch.buffer->dl > 0)) 560 chn_intr(sb->pch.channel); 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 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 600 if (sb->bd_flags & BD_F_SB16) { 601 RANGE(speed, 5000, 45000); 602 sb_cmd(sb, 0x42 - play); 603 sb_cmd(sb, speed >> 8); 604 sb_cmd(sb, speed & 0xff); 605 } else { 606 u_char tconst; 607 int max_speed = 45000, tmp; 608 u_long flags; 609 610 /* here enforce speed limitations - max 22050 on sb 1.x*/ 611 if (sb->bd_id <= 0x200) 612 max_speed = 22050; 613 614 /* 615 * SB models earlier than SB Pro have low limit for the 616 * input rate. Note that this is only for input, but since 617 * we do not support separate values for rec & play.... 618 */ 619 if (!play) { 620 if (sb->bd_id <= 0x200) 621 max_speed = 13000; 622 else 623 if (sb->bd_id < 0x300) 624 max_speed = 15000; 625 } 626 RANGE(speed, 4000, max_speed); 627 if (stereo) 628 speed <<= 1; 629 630 /* 631 * Now the speed should be valid. Compute the value to be 632 * programmed into the board. 633 */ 634 if (speed > 22050) { /* High speed mode on 2.01/3.xx */ 635 tconst = (u_char) 636 ((65536 - ((256000000 + speed / 2) / speed)) 637 >> 8); 638 sb->bd_flags |= BD_F_HISPEED; 639 tmp = 65536 - (tconst << 8); 640 speed = (256000000 + tmp / 2) / tmp; 641 } else { 642 sb->bd_flags &= ~BD_F_HISPEED; 643 tconst = (256 - ((1000000 + speed / 2) / speed)) & 0xff; 644 tmp = 256 - tconst; 645 speed = (1000000 + tmp / 2) / tmp; 646 } 647 flags = spltty(); 648 sb_cmd1(sb, 0x40, tconst); /* set time constant */ 649 splx(flags); 650 if (stereo) 651 speed >>= 1; 652 } 653 ch->spd = speed; 654 return speed; 655} 656 657static int 658sb_start(struct sb_chinfo *ch) 659{ 660 struct sb_info *sb = ch->parent; 661 int play = (ch->dir == PCMDIR_PLAY)? 1 : 0; 662 int b16 = (ch->fmt & AFMT_S16_LE)? 1 : 0; 663 int stereo = (ch->fmt & AFMT_STEREO)? 1 : 0; 664 int l = ch->buffer->dl; 665 int dh = ch->buffer->chan > 3; 666 u_char i1, i2; 667 668 if (b16 || dh) 669 l >>= 1; 670 l--; 671 672 if (play) 673 sb_cmd(sb, DSP_CMD_SPKON); 674 675 if (sb->bd_flags & BD_F_SB16) { 676 i1 = DSP_F16_AUTO | DSP_F16_FIFO_ON; 677 i1 |= play? DSP_F16_DAC : DSP_F16_ADC; 678 i1 |= (b16 || dh)? DSP_DMA16 : DSP_DMA8; 679 i2 = (stereo? DSP_F16_STEREO : 0) | (b16? DSP_F16_SIGNED : 0); 680 sb_cmd(sb, i1); 681 sb_cmd2(sb, i2, l); 682 } else { 683 if (sb->bd_flags & BD_F_HISPEED) 684 i1 = play? 0x90 : 0x98; 685 else 686 i1 = play? 0x1c : 0x2c; 687 sb_setmixer(sb, 0x0e, stereo? 2 : 0); 688 sb_cmd2(sb, 0x48, l); 689 sb_cmd(sb, i1); 690 } 691 sb->bd_flags |= BD_F_DMARUN << b16; 692 return 0; 693} 694 695static int 696sb_stop(struct sb_chinfo *ch) 697{ 698 struct sb_info *sb = ch->parent; 699 int play = (ch->dir == PCMDIR_PLAY)? 1 : 0; 700 int b16 = (ch->fmt & AFMT_S16_LE)? 1 : 0; 701 702 if (sb->bd_flags & BD_F_HISPEED) 703 sb_reset_dsp(sb); 704 else { 705 sb_cmd(sb, b16? DSP_CMD_DMAPAUSE_16 : DSP_CMD_DMAPAUSE_8); 706 /* 707 * The above seems to have the undocumented side effect of 708 * blocking the other side as well. If the other 709 * channel was active (SB16) I have to re-enable it :( 710 */ 711 if (sb->bd_flags & (BD_F_DMARUN << (1 - b16))) 712 sb_cmd(sb, b16? 0xd4 : 0xd6 ); 713 } 714 if (play) 715 sb_cmd(sb, DSP_CMD_SPKOFF); /* speaker off */ 716 sb->bd_flags &= ~(BD_F_DMARUN << b16); 717 return 0; 718} 719 720/* channel interface */ 721static void * 722sbchan_init(void *devinfo, snd_dbuf *b, pcm_channel *c, int dir) 723{ 724 struct sb_info *sb = devinfo; 725 struct sb_chinfo *ch = (dir == PCMDIR_PLAY)? &sb->pch : &sb->rch; 726 int dch, dl, dh; 727 728 ch->parent = sb; 729 ch->channel = c; 730 ch->buffer = b; 731 ch->buffer->bufsize = DSP_BUFFSIZE; 732 if (chn_allocbuf(ch->buffer, sb->parent_dmat) == -1) 733 return NULL; 734 dch = (dir == PCMDIR_PLAY)? 1 : 0; 735 if (sb->bd_flags & BD_F_SB16X) 736 dch = !dch; 737 dl = rman_get_start(sb->drq1); 738 dh = sb->drq2? rman_get_start(sb->drq2) : dl; 739 ch->buffer->chan = dch? dh : dl; 740 return ch; 741} 742 743static int 744sbchan_setdir(void *data, int dir) 745{ 746 struct sb_chinfo *ch = data; 747 748 ch->dir = dir; 749 return 0; 750} 751 752static int 753sbchan_setformat(void *data, u_int32_t format) 754{ 755 struct sb_chinfo *ch = data; 756 757 ch->fmt = format; 758 return 0; 759} 760 761static int 762sbchan_setspeed(void *data, u_int32_t speed) 763{ 764 struct sb_chinfo *ch = data; 765 766 ch->spd = speed; 767 return sb_speed(ch); 768} 769 770static int 771sbchan_setblocksize(void *data, u_int32_t blocksize) 772{ 773 return blocksize; 774} 775 776static int 777sbchan_trigger(void *data, int go) 778{ 779 struct sb_chinfo *ch = data; 780 781 if (go == PCMTRIG_EMLDMAWR) 782 return 0; 783 784 buf_isadma(ch->buffer, go); 785 if (go == PCMTRIG_START) 786 sb_start(ch); 787 else 788 sb_stop(ch); 789 return 0; 790} 791 792static int 793sbchan_getptr(void *data) 794{ 795 struct sb_chinfo *ch = data; 796 797 return buf_isadmaptr(ch->buffer); 798} 799 800static pcmchan_caps * 801sbchan_getcaps(void *data) 802{ 803 struct sb_chinfo *ch = data; 804 int p = (ch->dir == PCMDIR_PLAY)? 1 : 0; 805 806 if (ch->parent->bd_id < 0x300) 807 return p? &sb_playcaps : &sb_reccaps; 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 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 */ 1041 if (!(sb->bd_flags & BD_F_ESS)) 1042 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 */ 1051 sb_setmixer(sb, 0x3d, 0); /* make all inputs-l off */ 1052 sb_setmixer(sb, 0x3e, 0); /* make all inputs-r off */ 1053 } 1054 return 0; 1055} 1056 1057static int 1058sbmix_set(snd_mixer *m, unsigned dev, unsigned left, unsigned right) 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: 1067 if (sb->bd_flags & BD_F_ESS) 1068 iomap = &ess_mix; 1069 else 1070 iomap = &sbpro_mix; 1071 break; 1072 1073 case BD_F_MIX_CT1745: 1074 iomap = &sb16_mix; 1075 break; 1076 1077 default: 1078 return -1; 1079 } 1080 1081 /* Change left channel */ 1082 regoffs = (*iomap)[dev][LEFT_CHN].regno; 1083 if (regoffs != 0) { 1084 val = sb_getmixer(sb, regoffs); 1085 change_bits(iomap, &val, dev, LEFT_CHN, left); 1086 sb_setmixer(sb, regoffs, val); 1087 } 1088 1089 /* Change right channel */ 1090 regoffs = (*iomap)[dev][RIGHT_CHN].regno; 1091 if (regoffs != 0) { 1092 val = sb_getmixer(sb, regoffs); /* Read the new one */ 1093 change_bits(iomap, &val, dev, RIGHT_CHN, right); 1094 sb_setmixer(sb, regoffs, val); 1095 } else 1096 right = left; 1097 1098 return left | (right << 8); 1099} 1100 1101static int 1102sbmix_setrecsrc(snd_mixer *m, u_int32_t src) 1103{ 1104 struct sb_info *sb = mix_getdevinfo(m); 1105 u_char recdev; 1106 1107 switch (sb->bd_flags & BD_F_MIX_MASK) { 1108 case BD_F_MIX_CT1345: 1109 if (src == SOUND_MASK_LINE) 1110 recdev = 0x06; 1111 else if (src == SOUND_MASK_CD) 1112 recdev = 0x02; 1113 else { /* default: mic */ 1114 src = SOUND_MASK_MIC; 1115 recdev = 0; 1116 } 1117 sb_setmixer(sb, RECORD_SRC, recdev | 1118 (sb_getmixer(sb, RECORD_SRC) & ~0x07)); 1119 break; 1120 1121 case BD_F_MIX_CT1745: /* sb16 */ 1122 recdev = 0; 1123 if (src & SOUND_MASK_MIC) 1124 recdev |= 0x01; /* mono mic */ 1125 if (src & SOUND_MASK_CD) 1126 recdev |= 0x06; /* l+r cd */ 1127 if (src & SOUND_MASK_LINE) 1128 recdev |= 0x18; /* l+r line */ 1129 if (src & SOUND_MASK_SYNTH) 1130 recdev |= 0x60; /* l+r midi */ 1131 sb_setmixer(sb, SB16_IMASK_L, recdev); 1132 sb_setmixer(sb, SB16_IMASK_R, recdev); 1133 /* 1134 * since the same volume controls apply to the input and 1135 * output sections, the best approach to have a consistent 1136 * behaviour among cards would be to disable the output path 1137 * on devices which are used to record. 1138 * However, since users like to have feedback, we only disable 1139 * the mic -- permanently. 1140 */ 1141 sb_setmixer(sb, SB16_OMASK, 0x1f & ~1); 1142 break; 1143 } 1144 return src; 1145} 1146 1147static int 1148sbsbc_probe(device_t dev) 1149{ 1150 char buf[64]; 1151 uintptr_t func, ver, r, f; 1152 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; 1161 snprintf(buf, sizeof buf, "SB DSP %d.%02d%s%s", (int) ver >> 8, (int) ver & 0xff, 1162 (f & BD_F_ESS)? " (ESS mode)" : "", 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) 1171{ 1172 struct sb_info *sb; 1173 uintptr_t ver; 1174 1175 sb = (struct sb_info *)malloc(sizeof *sb, M_DEVBUF, M_NOWAIT); 1176 if (!sb) 1177 return ENXIO; 1178 bzero(sb, sizeof *sb); 1179 1180 BUS_READ_IVAR(device_get_parent(dev), dev, 1, &ver); 1181 sb->bd_id = ver & 0x0000ffff; 1182 sb->bd_flags = (ver & 0xffff0000) >> 16; 1183 1184 return sb_doattach(dev, sb); 1185} 1186 1187static device_method_t sbsbc_methods[] = { 1188 /* Device interface */ 1189 DEVMETHOD(device_probe, sbsbc_probe), 1190 DEVMETHOD(device_attach, sbsbc_attach), 1191 1192 { 0, 0 } 1193}; 1194 1195static driver_t sbsbc_driver = { 1196 "pcm", 1197 sbsbc_methods, 1198 sizeof(snddev_info), 1199}; 1200 1201DRIVER_MODULE(sbsbc, sbc, sbsbc_driver, pcm_devclass, 0, 0); 1202 1203 1204 1205