1 /*- 2 * Copyright (c) 1999 Seigo Tanimura 3 * All rights reserved. 4 * 5 * Portions of this source are based on cwcealdr.cpp and dhwiface.cpp in 6 * cwcealdr1.zip, the sample sources by Crystal Semiconductor. 7 * Copyright (c) 1996-1998 Crystal Semiconductor Corp. 8 * 9 * Redistribution and use in source and binary forms, with or without 10 * modification, are permitted provided that the following conditions 11 * are met: 12 * 1. Redistributions of source code must retain the above copyright 13 * notice, this list of conditions and the following disclaimer. 14 * 2. Redistributions in binary form must reproduce the above copyright 15 * notice, this list of conditions and the following disclaimer in the 16 * documentation and/or other materials provided with the distribution. 17 * 18 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 19 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 20 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 21 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 22 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 23 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 24 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 25 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 26 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 27 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 28 * SUCH DAMAGE. 29 */ 30 31 #include <sys/soundcard.h> 32 #include <dev/sound/pcm/sound.h> 33 #include <dev/sound/pcm/ac97.h> 34 #include <dev/sound/chip.h> 35 #include <dev/sound/pci/csareg.h> 36 #include <dev/sound/pci/csavar.h> 37 38 #include <dev/pci/pcireg.h> 39 #include <dev/pci/pcivar.h> 40 41 SND_DECLARE_FILE("$FreeBSD$"); 42 43 /* Buffer size on dma transfer. Fixed for CS416x. */ 44 #define CS461x_BUFFSIZE (4 * 1024) 45 46 #define GOF_PER_SEC 200 47 48 /* device private data */ 49 struct csa_info; 50 51 struct csa_chinfo { 52 struct csa_info *parent; 53 struct pcm_channel *channel; 54 struct snd_dbuf *buffer; 55 int dir; 56 u_int32_t fmt, spd; 57 int dma; 58 }; 59 60 struct csa_info { 61 csa_res res; /* resource */ 62 void *ih; /* Interrupt cookie */ 63 bus_dma_tag_t parent_dmat; /* DMA tag */ 64 struct csa_bridgeinfo *binfo; /* The state of the parent. */ 65 struct csa_card *card; 66 67 int active; 68 /* Contents of board's registers */ 69 u_long pfie; 70 u_long pctl; 71 u_long cctl; 72 struct csa_chinfo pch, rch; 73 }; 74 75 /* -------------------------------------------------------------------- */ 76 77 /* prototypes */ 78 static int csa_init(struct csa_info *); 79 static void csa_intr(void *); 80 static void csa_setplaysamplerate(csa_res *resp, u_long ulInRate); 81 static void csa_setcapturesamplerate(csa_res *resp, u_long ulOutRate); 82 static void csa_startplaydma(struct csa_info *csa); 83 static void csa_startcapturedma(struct csa_info *csa); 84 static void csa_stopplaydma(struct csa_info *csa); 85 static void csa_stopcapturedma(struct csa_info *csa); 86 static int csa_startdsp(csa_res *resp); 87 static int csa_allocres(struct csa_info *scp, device_t dev); 88 static void csa_releaseres(struct csa_info *scp, device_t dev); 89 90 static u_int32_t csa_playfmt[] = { 91 AFMT_U8, 92 AFMT_STEREO | AFMT_U8, 93 AFMT_S8, 94 AFMT_STEREO | AFMT_S8, 95 AFMT_S16_LE, 96 AFMT_STEREO | AFMT_S16_LE, 97 AFMT_S16_BE, 98 AFMT_STEREO | AFMT_S16_BE, 99 0 100 }; 101 static struct pcmchan_caps csa_playcaps = {8000, 48000, csa_playfmt, 0}; 102 103 static u_int32_t csa_recfmt[] = { 104 AFMT_S16_LE, 105 AFMT_STEREO | AFMT_S16_LE, 106 0 107 }; 108 static struct pcmchan_caps csa_reccaps = {11025, 48000, csa_recfmt, 0}; 109 110 /* -------------------------------------------------------------------- */ 111 112 static int 113 csa_active(struct csa_info *csa, int run) 114 { 115 int old, go; 116 117 old = csa->active; 118 csa->active += run; 119 120 if ((csa->active == 0 && old == 1) || (csa->active == 1 && old == 0)) { 121 go = csa->active; 122 if (csa->card->active) 123 return csa->card->active(go); 124 } 125 return 0; 126 } 127 128 /* -------------------------------------------------------------------- */ 129 /* ac97 codec */ 130 131 static int 132 csa_rdcd(kobj_t obj, void *devinfo, int regno) 133 { 134 u_int32_t data; 135 struct csa_info *csa = (struct csa_info *)devinfo; 136 137 csa_active(csa, 1); 138 if (csa_readcodec(&csa->res, regno + BA0_AC97_RESET, &data)) 139 data = 0; 140 csa_active(csa, -1); 141 142 return data; 143 } 144 145 static int 146 csa_wrcd(kobj_t obj, void *devinfo, int regno, u_int32_t data) 147 { 148 struct csa_info *csa = (struct csa_info *)devinfo; 149 150 csa_active(csa, 1); 151 csa_writecodec(&csa->res, regno + BA0_AC97_RESET, data); 152 csa_active(csa, -1); 153 154 return 0; 155 } 156 157 static kobj_method_t csa_ac97_methods[] = { 158 KOBJMETHOD(ac97_read, csa_rdcd), 159 KOBJMETHOD(ac97_write, csa_wrcd), 160 { 0, 0 } 161 }; 162 AC97_DECLARE(csa_ac97); 163 164 static void 165 csa_setplaysamplerate(csa_res *resp, u_long ulInRate) 166 { 167 u_long ulTemp1, ulTemp2; 168 u_long ulPhiIncr; 169 u_long ulCorrectionPerGOF, ulCorrectionPerSec; 170 u_long ulOutRate; 171 172 ulOutRate = 48000; 173 174 /* 175 * Compute the values used to drive the actual sample rate conversion. 176 * The following formulas are being computed, using inline assembly 177 * since we need to use 64 bit arithmetic to compute the values: 178 * 179 * ulPhiIncr = floor((Fs,in * 2^26) / Fs,out) 180 * ulCorrectionPerGOF = floor((Fs,in * 2^26 - Fs,out * ulPhiIncr) / 181 * GOF_PER_SEC) 182 * ulCorrectionPerSec = Fs,in * 2^26 - Fs,out * phiIncr - 183 * GOF_PER_SEC * ulCorrectionPerGOF 184 * 185 * i.e. 186 * 187 * ulPhiIncr:ulOther = dividend:remainder((Fs,in * 2^26) / Fs,out) 188 * ulCorrectionPerGOF:ulCorrectionPerSec = 189 * dividend:remainder(ulOther / GOF_PER_SEC) 190 */ 191 ulTemp1 = ulInRate << 16; 192 ulPhiIncr = ulTemp1 / ulOutRate; 193 ulTemp1 -= ulPhiIncr * ulOutRate; 194 ulTemp1 <<= 10; 195 ulPhiIncr <<= 10; 196 ulTemp2 = ulTemp1 / ulOutRate; 197 ulPhiIncr += ulTemp2; 198 ulTemp1 -= ulTemp2 * ulOutRate; 199 ulCorrectionPerGOF = ulTemp1 / GOF_PER_SEC; 200 ulTemp1 -= ulCorrectionPerGOF * GOF_PER_SEC; 201 ulCorrectionPerSec = ulTemp1; 202 203 /* 204 * Fill in the SampleRateConverter control block. 205 */ 206 csa_writemem(resp, BA1_PSRC, ((ulCorrectionPerSec << 16) & 0xFFFF0000) | (ulCorrectionPerGOF & 0xFFFF)); 207 csa_writemem(resp, BA1_PPI, ulPhiIncr); 208 } 209 210 static void 211 csa_setcapturesamplerate(csa_res *resp, u_long ulOutRate) 212 { 213 u_long ulPhiIncr, ulCoeffIncr, ulTemp1, ulTemp2; 214 u_long ulCorrectionPerGOF, ulCorrectionPerSec, ulInitialDelay; 215 u_long dwFrameGroupLength, dwCnt; 216 u_long ulInRate; 217 218 ulInRate = 48000; 219 220 /* 221 * We can only decimate by up to a factor of 1/9th the hardware rate. 222 * Return an error if an attempt is made to stray outside that limit. 223 */ 224 if((ulOutRate * 9) < ulInRate) 225 return; 226 227 /* 228 * We can not capture at at rate greater than the Input Rate (48000). 229 * Return an error if an attempt is made to stray outside that limit. 230 */ 231 if(ulOutRate > ulInRate) 232 return; 233 234 /* 235 * Compute the values used to drive the actual sample rate conversion. 236 * The following formulas are being computed, using inline assembly 237 * since we need to use 64 bit arithmetic to compute the values: 238 * 239 * ulCoeffIncr = -floor((Fs,out * 2^23) / Fs,in) 240 * ulPhiIncr = floor((Fs,in * 2^26) / Fs,out) 241 * ulCorrectionPerGOF = floor((Fs,in * 2^26 - Fs,out * ulPhiIncr) / 242 * GOF_PER_SEC) 243 * ulCorrectionPerSec = Fs,in * 2^26 - Fs,out * phiIncr - 244 * GOF_PER_SEC * ulCorrectionPerGOF 245 * ulInitialDelay = ceil((24 * Fs,in) / Fs,out) 246 * 247 * i.e. 248 * 249 * ulCoeffIncr = neg(dividend((Fs,out * 2^23) / Fs,in)) 250 * ulPhiIncr:ulOther = dividend:remainder((Fs,in * 2^26) / Fs,out) 251 * ulCorrectionPerGOF:ulCorrectionPerSec = 252 * dividend:remainder(ulOther / GOF_PER_SEC) 253 * ulInitialDelay = dividend(((24 * Fs,in) + Fs,out - 1) / Fs,out) 254 */ 255 ulTemp1 = ulOutRate << 16; 256 ulCoeffIncr = ulTemp1 / ulInRate; 257 ulTemp1 -= ulCoeffIncr * ulInRate; 258 ulTemp1 <<= 7; 259 ulCoeffIncr <<= 7; 260 ulCoeffIncr += ulTemp1 / ulInRate; 261 ulCoeffIncr ^= 0xFFFFFFFF; 262 ulCoeffIncr++; 263 ulTemp1 = ulInRate << 16; 264 ulPhiIncr = ulTemp1 / ulOutRate; 265 ulTemp1 -= ulPhiIncr * ulOutRate; 266 ulTemp1 <<= 10; 267 ulPhiIncr <<= 10; 268 ulTemp2 = ulTemp1 / ulOutRate; 269 ulPhiIncr += ulTemp2; 270 ulTemp1 -= ulTemp2 * ulOutRate; 271 ulCorrectionPerGOF = ulTemp1 / GOF_PER_SEC; 272 ulTemp1 -= ulCorrectionPerGOF * GOF_PER_SEC; 273 ulCorrectionPerSec = ulTemp1; 274 ulInitialDelay = ((ulInRate * 24) + ulOutRate - 1) / ulOutRate; 275 276 /* 277 * Fill in the VariDecimate control block. 278 */ 279 csa_writemem(resp, BA1_CSRC, 280 ((ulCorrectionPerSec << 16) & 0xFFFF0000) | (ulCorrectionPerGOF & 0xFFFF)); 281 csa_writemem(resp, BA1_CCI, ulCoeffIncr); 282 csa_writemem(resp, BA1_CD, 283 (((BA1_VARIDEC_BUF_1 + (ulInitialDelay << 2)) << 16) & 0xFFFF0000) | 0x80); 284 csa_writemem(resp, BA1_CPI, ulPhiIncr); 285 286 /* 287 * Figure out the frame group length for the write back task. Basically, 288 * this is just the factors of 24000 (2^6*3*5^3) that are not present in 289 * the output sample rate. 290 */ 291 dwFrameGroupLength = 1; 292 for(dwCnt = 2; dwCnt <= 64; dwCnt *= 2) 293 { 294 if(((ulOutRate / dwCnt) * dwCnt) != 295 ulOutRate) 296 { 297 dwFrameGroupLength *= 2; 298 } 299 } 300 if(((ulOutRate / 3) * 3) != 301 ulOutRate) 302 { 303 dwFrameGroupLength *= 3; 304 } 305 for(dwCnt = 5; dwCnt <= 125; dwCnt *= 5) 306 { 307 if(((ulOutRate / dwCnt) * dwCnt) != 308 ulOutRate) 309 { 310 dwFrameGroupLength *= 5; 311 } 312 } 313 314 /* 315 * Fill in the WriteBack control block. 316 */ 317 csa_writemem(resp, BA1_CFG1, dwFrameGroupLength); 318 csa_writemem(resp, BA1_CFG2, (0x00800000 | dwFrameGroupLength)); 319 csa_writemem(resp, BA1_CCST, 0x0000FFFF); 320 csa_writemem(resp, BA1_CSPB, ((65536 * ulOutRate) / 24000)); 321 csa_writemem(resp, (BA1_CSPB + 4), 0x0000FFFF); 322 } 323 324 static void 325 csa_startplaydma(struct csa_info *csa) 326 { 327 csa_res *resp; 328 u_long ul; 329 330 if (!csa->pch.dma) { 331 resp = &csa->res; 332 ul = csa_readmem(resp, BA1_PCTL); 333 ul &= 0x0000ffff; 334 csa_writemem(resp, BA1_PCTL, ul | csa->pctl); 335 csa_writemem(resp, BA1_PVOL, 0x80008000); 336 csa->pch.dma = 1; 337 } 338 } 339 340 static void 341 csa_startcapturedma(struct csa_info *csa) 342 { 343 csa_res *resp; 344 u_long ul; 345 346 if (!csa->rch.dma) { 347 resp = &csa->res; 348 ul = csa_readmem(resp, BA1_CCTL); 349 ul &= 0xffff0000; 350 csa_writemem(resp, BA1_CCTL, ul | csa->cctl); 351 csa_writemem(resp, BA1_CVOL, 0x80008000); 352 csa->rch.dma = 1; 353 } 354 } 355 356 static void 357 csa_stopplaydma(struct csa_info *csa) 358 { 359 csa_res *resp; 360 u_long ul; 361 362 if (csa->pch.dma) { 363 resp = &csa->res; 364 ul = csa_readmem(resp, BA1_PCTL); 365 csa->pctl = ul & 0xffff0000; 366 csa_writemem(resp, BA1_PCTL, ul & 0x0000ffff); 367 csa_writemem(resp, BA1_PVOL, 0xffffffff); 368 csa->pch.dma = 0; 369 370 /* 371 * The bitwise pointer of the serial FIFO in the DSP 372 * seems to make an error upon starting or stopping the 373 * DSP. Clear the FIFO and correct the pointer if we 374 * are not capturing. 375 */ 376 if (!csa->rch.dma) { 377 csa_clearserialfifos(resp); 378 csa_writeio(resp, BA0_SERBSP, 0); 379 } 380 } 381 } 382 383 static void 384 csa_stopcapturedma(struct csa_info *csa) 385 { 386 csa_res *resp; 387 u_long ul; 388 389 if (csa->rch.dma) { 390 resp = &csa->res; 391 ul = csa_readmem(resp, BA1_CCTL); 392 csa->cctl = ul & 0x0000ffff; 393 csa_writemem(resp, BA1_CCTL, ul & 0xffff0000); 394 csa_writemem(resp, BA1_CVOL, 0xffffffff); 395 csa->rch.dma = 0; 396 397 /* 398 * The bitwise pointer of the serial FIFO in the DSP 399 * seems to make an error upon starting or stopping the 400 * DSP. Clear the FIFO and correct the pointer if we 401 * are not playing. 402 */ 403 if (!csa->pch.dma) { 404 csa_clearserialfifos(resp); 405 csa_writeio(resp, BA0_SERBSP, 0); 406 } 407 } 408 } 409 410 static int 411 csa_startdsp(csa_res *resp) 412 { 413 int i; 414 u_long ul; 415 416 /* 417 * Set the frame timer to reflect the number of cycles per frame. 418 */ 419 csa_writemem(resp, BA1_FRMT, 0xadf); 420 421 /* 422 * Turn on the run, run at frame, and DMA enable bits in the local copy of 423 * the SP control register. 424 */ 425 csa_writemem(resp, BA1_SPCR, SPCR_RUN | SPCR_RUNFR | SPCR_DRQEN); 426 427 /* 428 * Wait until the run at frame bit resets itself in the SP control 429 * register. 430 */ 431 ul = 0; 432 for (i = 0 ; i < 25 ; i++) { 433 /* 434 * Wait a little bit, so we don't issue PCI reads too frequently. 435 */ 436 DELAY(50); 437 /* 438 * Fetch the current value of the SP status register. 439 */ 440 ul = csa_readmem(resp, BA1_SPCR); 441 442 /* 443 * If the run at frame bit has reset, then stop waiting. 444 */ 445 if((ul & SPCR_RUNFR) == 0) 446 break; 447 } 448 /* 449 * If the run at frame bit never reset, then return an error. 450 */ 451 if((ul & SPCR_RUNFR) != 0) 452 return (EAGAIN); 453 454 return (0); 455 } 456 457 static int 458 csa_setupchan(struct csa_chinfo *ch) 459 { 460 struct csa_info *csa = ch->parent; 461 csa_res *resp = &csa->res; 462 u_long pdtc, tmp; 463 464 if (ch->dir == PCMDIR_PLAY) { 465 /* direction */ 466 csa_writemem(resp, BA1_PBA, sndbuf_getbufaddr(ch->buffer)); 467 468 /* format */ 469 csa->pfie = csa_readmem(resp, BA1_PFIE) & ~0x0000f03f; 470 if (!(ch->fmt & AFMT_SIGNED)) 471 csa->pfie |= 0x8000; 472 if (ch->fmt & AFMT_BIGENDIAN) 473 csa->pfie |= 0x4000; 474 if (!(ch->fmt & AFMT_STEREO)) 475 csa->pfie |= 0x2000; 476 if (ch->fmt & AFMT_8BIT) 477 csa->pfie |= 0x1000; 478 csa_writemem(resp, BA1_PFIE, csa->pfie); 479 480 tmp = 4; 481 if (ch->fmt & AFMT_16BIT) 482 tmp <<= 1; 483 if (ch->fmt & AFMT_STEREO) 484 tmp <<= 1; 485 tmp--; 486 487 pdtc = csa_readmem(resp, BA1_PDTC) & ~0x000001ff; 488 pdtc |= tmp; 489 csa_writemem(resp, BA1_PDTC, pdtc); 490 491 /* rate */ 492 csa_setplaysamplerate(resp, ch->spd); 493 } else if (ch->dir == PCMDIR_REC) { 494 /* direction */ 495 csa_writemem(resp, BA1_CBA, sndbuf_getbufaddr(ch->buffer)); 496 497 /* format */ 498 csa_writemem(resp, BA1_CIE, (csa_readmem(resp, BA1_CIE) & ~0x0000003f) | 0x00000001); 499 500 /* rate */ 501 csa_setcapturesamplerate(resp, ch->spd); 502 } 503 return 0; 504 } 505 506 /* -------------------------------------------------------------------- */ 507 /* channel interface */ 508 509 static void * 510 csachan_init(kobj_t obj, void *devinfo, struct snd_dbuf *b, struct pcm_channel *c, int dir) 511 { 512 struct csa_info *csa = devinfo; 513 struct csa_chinfo *ch = (dir == PCMDIR_PLAY)? &csa->pch : &csa->rch; 514 515 ch->parent = csa; 516 ch->channel = c; 517 ch->buffer = b; 518 ch->dir = dir; 519 if (sndbuf_alloc(ch->buffer, csa->parent_dmat, CS461x_BUFFSIZE) != 0) 520 return NULL; 521 return ch; 522 } 523 524 static int 525 csachan_setformat(kobj_t obj, void *data, u_int32_t format) 526 { 527 struct csa_chinfo *ch = data; 528 529 ch->fmt = format; 530 return 0; 531 } 532 533 static int 534 csachan_setspeed(kobj_t obj, void *data, u_int32_t speed) 535 { 536 struct csa_chinfo *ch = data; 537 538 ch->spd = speed; 539 return ch->spd; /* XXX calc real speed */ 540 } 541 542 static int 543 csachan_setblocksize(kobj_t obj, void *data, u_int32_t blocksize) 544 { 545 return CS461x_BUFFSIZE / 2; 546 } 547 548 static int 549 csachan_trigger(kobj_t obj, void *data, int go) 550 { 551 struct csa_chinfo *ch = data; 552 struct csa_info *csa = ch->parent; 553 554 if (go == PCMTRIG_EMLDMAWR || go == PCMTRIG_EMLDMARD) 555 return 0; 556 557 if (go == PCMTRIG_START) { 558 csa_active(csa, 1); 559 csa_setupchan(ch); 560 if (ch->dir == PCMDIR_PLAY) 561 csa_startplaydma(csa); 562 else 563 csa_startcapturedma(csa); 564 } else { 565 if (ch->dir == PCMDIR_PLAY) 566 csa_stopplaydma(csa); 567 else 568 csa_stopcapturedma(csa); 569 csa_active(csa, -1); 570 } 571 return 0; 572 } 573 574 static int 575 csachan_getptr(kobj_t obj, void *data) 576 { 577 struct csa_chinfo *ch = data; 578 struct csa_info *csa = ch->parent; 579 csa_res *resp; 580 int ptr; 581 582 resp = &csa->res; 583 584 if (ch->dir == PCMDIR_PLAY) { 585 ptr = csa_readmem(resp, BA1_PBA) - sndbuf_getbufaddr(ch->buffer); 586 if ((ch->fmt & AFMT_U8) != 0 || (ch->fmt & AFMT_S8) != 0) 587 ptr >>= 1; 588 } else { 589 ptr = csa_readmem(resp, BA1_CBA) - sndbuf_getbufaddr(ch->buffer); 590 if ((ch->fmt & AFMT_U8) != 0 || (ch->fmt & AFMT_S8) != 0) 591 ptr >>= 1; 592 } 593 594 return (ptr); 595 } 596 597 static struct pcmchan_caps * 598 csachan_getcaps(kobj_t obj, void *data) 599 { 600 struct csa_chinfo *ch = data; 601 return (ch->dir == PCMDIR_PLAY)? &csa_playcaps : &csa_reccaps; 602 } 603 604 static kobj_method_t csachan_methods[] = { 605 KOBJMETHOD(channel_init, csachan_init), 606 KOBJMETHOD(channel_setformat, csachan_setformat), 607 KOBJMETHOD(channel_setspeed, csachan_setspeed), 608 KOBJMETHOD(channel_setblocksize, csachan_setblocksize), 609 KOBJMETHOD(channel_trigger, csachan_trigger), 610 KOBJMETHOD(channel_getptr, csachan_getptr), 611 KOBJMETHOD(channel_getcaps, csachan_getcaps), 612 { 0, 0 } 613 }; 614 CHANNEL_DECLARE(csachan); 615 616 /* -------------------------------------------------------------------- */ 617 /* The interrupt handler */ 618 static void 619 csa_intr(void *p) 620 { 621 struct csa_info *csa = p; 622 623 if ((csa->binfo->hisr & HISR_VC0) != 0) 624 chn_intr(csa->pch.channel); 625 if ((csa->binfo->hisr & HISR_VC1) != 0) 626 chn_intr(csa->rch.channel); 627 } 628 629 /* -------------------------------------------------------------------- */ 630 631 /* 632 * Probe and attach the card 633 */ 634 635 static int 636 csa_init(struct csa_info *csa) 637 { 638 csa_res *resp; 639 640 resp = &csa->res; 641 642 csa->pfie = 0; 643 csa_stopplaydma(csa); 644 csa_stopcapturedma(csa); 645 646 if (csa_startdsp(resp)) 647 return (1); 648 649 /* Crank up the power on the DAC and ADC. */ 650 csa_setplaysamplerate(resp, 8000); 651 csa_setcapturesamplerate(resp, 8000); 652 653 return 0; 654 } 655 656 /* Allocates resources. */ 657 static int 658 csa_allocres(struct csa_info *csa, device_t dev) 659 { 660 csa_res *resp; 661 662 resp = &csa->res; 663 if (resp->io == NULL) { 664 resp->io = bus_alloc_resource_any(dev, SYS_RES_MEMORY, 665 &resp->io_rid, RF_ACTIVE); 666 if (resp->io == NULL) 667 return (1); 668 } 669 if (resp->mem == NULL) { 670 resp->mem = bus_alloc_resource_any(dev, SYS_RES_MEMORY, 671 &resp->mem_rid, RF_ACTIVE); 672 if (resp->mem == NULL) 673 return (1); 674 } 675 if (resp->irq == NULL) { 676 resp->irq = bus_alloc_resource_any(dev, SYS_RES_IRQ, 677 &resp->irq_rid, RF_ACTIVE | RF_SHAREABLE); 678 if (resp->irq == NULL) 679 return (1); 680 } 681 if (bus_dma_tag_create(/*parent*/NULL, /*alignment*/CS461x_BUFFSIZE, /*boundary*/CS461x_BUFFSIZE, 682 /*lowaddr*/BUS_SPACE_MAXADDR_32BIT, 683 /*highaddr*/BUS_SPACE_MAXADDR, 684 /*filter*/NULL, /*filterarg*/NULL, 685 /*maxsize*/CS461x_BUFFSIZE, /*nsegments*/1, /*maxsegz*/0x3ffff, 686 /*flags*/0, /*lockfunc*/busdma_lock_mutex, 687 /*lockarg*/&Giant, &csa->parent_dmat) != 0) 688 return (1); 689 690 return (0); 691 } 692 693 /* Releases resources. */ 694 static void 695 csa_releaseres(struct csa_info *csa, device_t dev) 696 { 697 csa_res *resp; 698 699 resp = &csa->res; 700 if (resp->irq != NULL) { 701 if (csa->ih) 702 bus_teardown_intr(dev, resp->irq, csa->ih); 703 bus_release_resource(dev, SYS_RES_IRQ, resp->irq_rid, resp->irq); 704 resp->irq = NULL; 705 } 706 if (resp->io != NULL) { 707 bus_release_resource(dev, SYS_RES_MEMORY, resp->io_rid, resp->io); 708 resp->io = NULL; 709 } 710 if (resp->mem != NULL) { 711 bus_release_resource(dev, SYS_RES_MEMORY, resp->mem_rid, resp->mem); 712 resp->mem = NULL; 713 } 714 if (csa->parent_dmat != NULL) { 715 bus_dma_tag_destroy(csa->parent_dmat); 716 csa->parent_dmat = NULL; 717 } 718 if (csa != NULL) { 719 free(csa, M_DEVBUF); 720 csa = NULL; 721 } 722 } 723 724 static int 725 pcmcsa_probe(device_t dev) 726 { 727 char *s; 728 struct sndcard_func *func; 729 730 /* The parent device has already been probed. */ 731 732 func = device_get_ivars(dev); 733 if (func == NULL || func->func != SCF_PCM) 734 return (ENXIO); 735 736 s = "CS461x PCM Audio"; 737 738 device_set_desc(dev, s); 739 return (0); 740 } 741 742 static int 743 pcmcsa_attach(device_t dev) 744 { 745 struct csa_info *csa; 746 csa_res *resp; 747 int unit; 748 char status[SND_STATUSLEN]; 749 struct ac97_info *codec; 750 struct sndcard_func *func; 751 752 csa = malloc(sizeof(*csa), M_DEVBUF, M_NOWAIT | M_ZERO); 753 if (csa == NULL) 754 return (ENOMEM); 755 unit = device_get_unit(dev); 756 func = device_get_ivars(dev); 757 csa->binfo = func->varinfo; 758 /* 759 * Fake the status of DMA so that the initial value of 760 * PCTL and CCTL can be stored into csa->pctl and csa->cctl, 761 * respectively. 762 */ 763 csa->pch.dma = csa->rch.dma = 1; 764 csa->active = 0; 765 csa->card = csa->binfo->card; 766 767 /* Allocate the resources. */ 768 resp = &csa->res; 769 resp->io_rid = PCIR_BAR(0); 770 resp->mem_rid = PCIR_BAR(1); 771 resp->irq_rid = 0; 772 if (csa_allocres(csa, dev)) { 773 csa_releaseres(csa, dev); 774 return (ENXIO); 775 } 776 777 csa_active(csa, 1); 778 if (csa_init(csa)) { 779 csa_releaseres(csa, dev); 780 return (ENXIO); 781 } 782 codec = AC97_CREATE(dev, csa, csa_ac97); 783 if (codec == NULL) { 784 csa_releaseres(csa, dev); 785 return (ENXIO); 786 } 787 if (csa->card->inv_eapd) 788 ac97_setflags(codec, AC97_F_EAPD_INV); 789 if (mixer_init(dev, ac97_getmixerclass(), codec) == -1) { 790 ac97_destroy(codec); 791 csa_releaseres(csa, dev); 792 return (ENXIO); 793 } 794 795 snprintf(status, SND_STATUSLEN, "at irq %ld %s", 796 rman_get_start(resp->irq),PCM_KLDSTRING(snd_csa)); 797 798 /* Enable interrupt. */ 799 if (snd_setup_intr(dev, resp->irq, 0, csa_intr, csa, &csa->ih)) { 800 ac97_destroy(codec); 801 csa_releaseres(csa, dev); 802 return (ENXIO); 803 } 804 csa_writemem(resp, BA1_PFIE, csa_readmem(resp, BA1_PFIE) & ~0x0000f03f); 805 csa_writemem(resp, BA1_CIE, (csa_readmem(resp, BA1_CIE) & ~0x0000003f) | 0x00000001); 806 csa_active(csa, -1); 807 808 if (pcm_register(dev, csa, 1, 1)) { 809 ac97_destroy(codec); 810 csa_releaseres(csa, dev); 811 return (ENXIO); 812 } 813 pcm_addchan(dev, PCMDIR_REC, &csachan_class, csa); 814 pcm_addchan(dev, PCMDIR_PLAY, &csachan_class, csa); 815 pcm_setstatus(dev, status); 816 817 return (0); 818 } 819 820 static int 821 pcmcsa_detach(device_t dev) 822 { 823 int r; 824 struct csa_info *csa; 825 826 r = pcm_unregister(dev); 827 if (r) 828 return r; 829 830 csa = pcm_getdevinfo(dev); 831 csa_releaseres(csa, dev); 832 833 return 0; 834 } 835 836 static device_method_t pcmcsa_methods[] = { 837 /* Device interface */ 838 DEVMETHOD(device_probe , pcmcsa_probe ), 839 DEVMETHOD(device_attach, pcmcsa_attach), 840 DEVMETHOD(device_detach, pcmcsa_detach), 841 842 { 0, 0 }, 843 }; 844 845 static driver_t pcmcsa_driver = { 846 "pcm", 847 pcmcsa_methods, 848 PCM_SOFTC_SIZE, 849 }; 850 851 DRIVER_MODULE(snd_csapcm, csa, pcmcsa_driver, pcm_devclass, 0, 0); 852 MODULE_DEPEND(snd_csapcm, sound, SOUND_MINVER, SOUND_PREFVER, SOUND_MAXVER); 853 MODULE_DEPEND(snd_csapcm, snd_csa, 1, 1, 1); 854 MODULE_VERSION(snd_csapcm, 1); 855