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