1 /* 2 * Copyright (c) by Jaroslav Kysela <perex@suse.cz> 3 * Abramo Bagnara <abramo@alsa-project.org> 4 * Cirrus Logic, Inc. 5 * Routines for control of Cirrus Logic CS461x chips 6 * 7 * KNOWN BUGS: 8 * - Sometimes the SPDIF input DSP tasks get's unsynchronized 9 * and the SPDIF get somewhat "distorcionated", or/and left right channel 10 * are swapped. To get around this problem when it happens, mute and unmute 11 * the SPDIF input mixer controll. 12 * - On the Hercules Game Theater XP the amplifier are sometimes turned 13 * off on inadecuate moments which causes distorcions on sound. 14 * 15 * TODO: 16 * - Secondary CODEC on some soundcards 17 * - SPDIF input support for other sample rates then 48khz 18 * - Posibility to mix the SPDIF output with analog sources. 19 * - PCM channels for Center and LFE on secondary codec 20 * 21 * NOTE: with CONFIG_SND_CS46XX_NEW_DSP unset uses old DSP image (which 22 * is default configuration), no SPDIF, no secondary codec, no 23 * multi channel PCM. But known to work. 24 * 25 * FINALLY: A credit to the developers Tom and Jordan 26 * at Cirrus for have helping me out with the DSP, however we 27 * still don't have sufficient documentation and technical 28 * references to be able to implement all fancy feutures 29 * supported by the cs46xx DSP's. 30 * Benny <benny@hostmobility.com> 31 * 32 * This program is free software; you can redistribute it and/or modify 33 * it under the terms of the GNU General Public License as published by 34 * the Free Software Foundation; either version 2 of the License, or 35 * (at your option) any later version. 36 * 37 * This program is distributed in the hope that it will be useful, 38 * but WITHOUT ANY WARRANTY; without even the implied warranty of 39 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 40 * GNU General Public License for more details. 41 * 42 * You should have received a copy of the GNU General Public License 43 * along with this program; if not, write to the Free Software 44 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 45 * 46 */ 47 48 #include <sound/driver.h> 49 #include <linux/delay.h> 50 #include <linux/pci.h> 51 #include <linux/pm.h> 52 #include <linux/init.h> 53 #include <linux/interrupt.h> 54 #include <linux/slab.h> 55 #include <linux/gameport.h> 56 57 #include <sound/core.h> 58 #include <sound/control.h> 59 #include <sound/info.h> 60 #include <sound/pcm.h> 61 #include <sound/pcm_params.h> 62 #include <sound/cs46xx.h> 63 64 #include <asm/io.h> 65 66 #include "cs46xx_lib.h" 67 #include "dsp_spos.h" 68 69 static void amp_voyetra(cs46xx_t *chip, int change); 70 71 #ifdef CONFIG_SND_CS46XX_NEW_DSP 72 static snd_pcm_ops_t snd_cs46xx_playback_rear_ops; 73 static snd_pcm_ops_t snd_cs46xx_playback_indirect_rear_ops; 74 static snd_pcm_ops_t snd_cs46xx_playback_clfe_ops; 75 static snd_pcm_ops_t snd_cs46xx_playback_indirect_clfe_ops; 76 static snd_pcm_ops_t snd_cs46xx_playback_iec958_ops; 77 static snd_pcm_ops_t snd_cs46xx_playback_indirect_iec958_ops; 78 #endif 79 80 static snd_pcm_ops_t snd_cs46xx_playback_ops; 81 static snd_pcm_ops_t snd_cs46xx_playback_indirect_ops; 82 static snd_pcm_ops_t snd_cs46xx_capture_ops; 83 static snd_pcm_ops_t snd_cs46xx_capture_indirect_ops; 84 85 static unsigned short snd_cs46xx_codec_read(cs46xx_t *chip, 86 unsigned short reg, 87 int codec_index) 88 { 89 int count; 90 unsigned short result,tmp; 91 u32 offset = 0; 92 snd_assert ( (codec_index == CS46XX_PRIMARY_CODEC_INDEX) || 93 (codec_index == CS46XX_SECONDARY_CODEC_INDEX), 94 return -EINVAL); 95 96 chip->active_ctrl(chip, 1); 97 98 if (codec_index == CS46XX_SECONDARY_CODEC_INDEX) 99 offset = CS46XX_SECONDARY_CODEC_OFFSET; 100 101 /* 102 * 1. Write ACCAD = Command Address Register = 46Ch for AC97 register address 103 * 2. Write ACCDA = Command Data Register = 470h for data to write to AC97 104 * 3. Write ACCTL = Control Register = 460h for initiating the write7---55 105 * 4. Read ACCTL = 460h, DCV should be reset by now and 460h = 17h 106 * 5. if DCV not cleared, break and return error 107 * 6. Read ACSTS = Status Register = 464h, check VSTS bit 108 */ 109 110 snd_cs46xx_peekBA0(chip, BA0_ACSDA + offset); 111 112 tmp = snd_cs46xx_peekBA0(chip, BA0_ACCTL); 113 if ((tmp & ACCTL_VFRM) == 0) { 114 snd_printk(KERN_WARNING "cs46xx: ACCTL_VFRM not set 0x%x\n",tmp); 115 snd_cs46xx_pokeBA0(chip, BA0_ACCTL, (tmp & (~ACCTL_ESYN)) | ACCTL_VFRM ); 116 msleep(50); 117 tmp = snd_cs46xx_peekBA0(chip, BA0_ACCTL + offset); 118 snd_cs46xx_pokeBA0(chip, BA0_ACCTL, tmp | ACCTL_ESYN | ACCTL_VFRM ); 119 120 } 121 122 /* 123 * Setup the AC97 control registers on the CS461x to send the 124 * appropriate command to the AC97 to perform the read. 125 * ACCAD = Command Address Register = 46Ch 126 * ACCDA = Command Data Register = 470h 127 * ACCTL = Control Register = 460h 128 * set DCV - will clear when process completed 129 * set CRW - Read command 130 * set VFRM - valid frame enabled 131 * set ESYN - ASYNC generation enabled 132 * set RSTN - ARST# inactive, AC97 codec not reset 133 */ 134 135 snd_cs46xx_pokeBA0(chip, BA0_ACCAD, reg); 136 snd_cs46xx_pokeBA0(chip, BA0_ACCDA, 0); 137 if (codec_index == CS46XX_PRIMARY_CODEC_INDEX) { 138 snd_cs46xx_pokeBA0(chip, BA0_ACCTL,/* clear ACCTL_DCV */ ACCTL_CRW | 139 ACCTL_VFRM | ACCTL_ESYN | 140 ACCTL_RSTN); 141 snd_cs46xx_pokeBA0(chip, BA0_ACCTL, ACCTL_DCV | ACCTL_CRW | 142 ACCTL_VFRM | ACCTL_ESYN | 143 ACCTL_RSTN); 144 } else { 145 snd_cs46xx_pokeBA0(chip, BA0_ACCTL, ACCTL_DCV | ACCTL_TC | 146 ACCTL_CRW | ACCTL_VFRM | ACCTL_ESYN | 147 ACCTL_RSTN); 148 } 149 150 /* 151 * Wait for the read to occur. 152 */ 153 for (count = 0; count < 1000; count++) { 154 /* 155 * First, we want to wait for a short time. 156 */ 157 udelay(10); 158 /* 159 * Now, check to see if the read has completed. 160 * ACCTL = 460h, DCV should be reset by now and 460h = 17h 161 */ 162 if (!(snd_cs46xx_peekBA0(chip, BA0_ACCTL) & ACCTL_DCV)) 163 goto ok1; 164 } 165 166 snd_printk("AC'97 read problem (ACCTL_DCV), reg = 0x%x\n", reg); 167 result = 0xffff; 168 goto end; 169 170 ok1: 171 /* 172 * Wait for the valid status bit to go active. 173 */ 174 for (count = 0; count < 100; count++) { 175 /* 176 * Read the AC97 status register. 177 * ACSTS = Status Register = 464h 178 * VSTS - Valid Status 179 */ 180 if (snd_cs46xx_peekBA0(chip, BA0_ACSTS + offset) & ACSTS_VSTS) 181 goto ok2; 182 udelay(10); 183 } 184 185 snd_printk("AC'97 read problem (ACSTS_VSTS), codec_index %d, reg = 0x%x\n", codec_index, reg); 186 result = 0xffff; 187 goto end; 188 189 ok2: 190 /* 191 * Read the data returned from the AC97 register. 192 * ACSDA = Status Data Register = 474h 193 */ 194 #if 0 195 printk("e) reg = 0x%x, val = 0x%x, BA0_ACCAD = 0x%x\n", reg, 196 snd_cs46xx_peekBA0(chip, BA0_ACSDA), 197 snd_cs46xx_peekBA0(chip, BA0_ACCAD)); 198 #endif 199 200 //snd_cs46xx_peekBA0(chip, BA0_ACCAD); 201 result = snd_cs46xx_peekBA0(chip, BA0_ACSDA + offset); 202 end: 203 chip->active_ctrl(chip, -1); 204 return result; 205 } 206 207 static unsigned short snd_cs46xx_ac97_read(ac97_t * ac97, 208 unsigned short reg) 209 { 210 cs46xx_t *chip = ac97->private_data; 211 unsigned short val; 212 int codec_index = ac97->num; 213 214 snd_assert(codec_index == CS46XX_PRIMARY_CODEC_INDEX || 215 codec_index == CS46XX_SECONDARY_CODEC_INDEX, 216 return 0xffff); 217 218 val = snd_cs46xx_codec_read(chip, reg, codec_index); 219 220 return val; 221 } 222 223 224 static void snd_cs46xx_codec_write(cs46xx_t *chip, 225 unsigned short reg, 226 unsigned short val, 227 int codec_index) 228 { 229 int count; 230 231 snd_assert ((codec_index == CS46XX_PRIMARY_CODEC_INDEX) || 232 (codec_index == CS46XX_SECONDARY_CODEC_INDEX), 233 return); 234 235 chip->active_ctrl(chip, 1); 236 237 /* 238 * 1. Write ACCAD = Command Address Register = 46Ch for AC97 register address 239 * 2. Write ACCDA = Command Data Register = 470h for data to write to AC97 240 * 3. Write ACCTL = Control Register = 460h for initiating the write 241 * 4. Read ACCTL = 460h, DCV should be reset by now and 460h = 07h 242 * 5. if DCV not cleared, break and return error 243 */ 244 245 /* 246 * Setup the AC97 control registers on the CS461x to send the 247 * appropriate command to the AC97 to perform the read. 248 * ACCAD = Command Address Register = 46Ch 249 * ACCDA = Command Data Register = 470h 250 * ACCTL = Control Register = 460h 251 * set DCV - will clear when process completed 252 * reset CRW - Write command 253 * set VFRM - valid frame enabled 254 * set ESYN - ASYNC generation enabled 255 * set RSTN - ARST# inactive, AC97 codec not reset 256 */ 257 snd_cs46xx_pokeBA0(chip, BA0_ACCAD , reg); 258 snd_cs46xx_pokeBA0(chip, BA0_ACCDA , val); 259 snd_cs46xx_peekBA0(chip, BA0_ACCTL); 260 261 if (codec_index == CS46XX_PRIMARY_CODEC_INDEX) { 262 snd_cs46xx_pokeBA0(chip, BA0_ACCTL, /* clear ACCTL_DCV */ ACCTL_VFRM | 263 ACCTL_ESYN | ACCTL_RSTN); 264 snd_cs46xx_pokeBA0(chip, BA0_ACCTL, ACCTL_DCV | ACCTL_VFRM | 265 ACCTL_ESYN | ACCTL_RSTN); 266 } else { 267 snd_cs46xx_pokeBA0(chip, BA0_ACCTL, ACCTL_DCV | ACCTL_TC | 268 ACCTL_VFRM | ACCTL_ESYN | ACCTL_RSTN); 269 } 270 271 for (count = 0; count < 4000; count++) { 272 /* 273 * First, we want to wait for a short time. 274 */ 275 udelay(10); 276 /* 277 * Now, check to see if the write has completed. 278 * ACCTL = 460h, DCV should be reset by now and 460h = 07h 279 */ 280 if (!(snd_cs46xx_peekBA0(chip, BA0_ACCTL) & ACCTL_DCV)) { 281 goto end; 282 } 283 } 284 snd_printk("AC'97 write problem, codec_index = %d, reg = 0x%x, val = 0x%x\n", codec_index, reg, val); 285 end: 286 chip->active_ctrl(chip, -1); 287 } 288 289 static void snd_cs46xx_ac97_write(ac97_t *ac97, 290 unsigned short reg, 291 unsigned short val) 292 { 293 cs46xx_t *chip = ac97->private_data; 294 int codec_index = ac97->num; 295 296 snd_assert(codec_index == CS46XX_PRIMARY_CODEC_INDEX || 297 codec_index == CS46XX_SECONDARY_CODEC_INDEX, 298 return); 299 300 snd_cs46xx_codec_write(chip, reg, val, codec_index); 301 } 302 303 304 /* 305 * Chip initialization 306 */ 307 308 int snd_cs46xx_download(cs46xx_t *chip, 309 u32 *src, 310 unsigned long offset, 311 unsigned long len) 312 { 313 void __iomem *dst; 314 unsigned int bank = offset >> 16; 315 offset = offset & 0xffff; 316 317 snd_assert(!(offset & 3) && !(len & 3), return -EINVAL); 318 dst = chip->region.idx[bank+1].remap_addr + offset; 319 len /= sizeof(u32); 320 321 /* writel already converts 32-bit value to right endianess */ 322 while (len-- > 0) { 323 writel(*src++, dst); 324 dst += sizeof(u32); 325 } 326 return 0; 327 } 328 329 #ifdef CONFIG_SND_CS46XX_NEW_DSP 330 331 #include "imgs/cwc4630.h" 332 #include "imgs/cwcasync.h" 333 #include "imgs/cwcsnoop.h" 334 #include "imgs/cwcbinhack.h" 335 #include "imgs/cwcdma.h" 336 337 int snd_cs46xx_clear_BA1(cs46xx_t *chip, 338 unsigned long offset, 339 unsigned long len) 340 { 341 void __iomem *dst; 342 unsigned int bank = offset >> 16; 343 offset = offset & 0xffff; 344 345 snd_assert(!(offset & 3) && !(len & 3), return -EINVAL); 346 dst = chip->region.idx[bank+1].remap_addr + offset; 347 len /= sizeof(u32); 348 349 /* writel already converts 32-bit value to right endianess */ 350 while (len-- > 0) { 351 writel(0, dst); 352 dst += sizeof(u32); 353 } 354 return 0; 355 } 356 357 #else /* old DSP image */ 358 359 #include "cs46xx_image.h" 360 361 int snd_cs46xx_download_image(cs46xx_t *chip) 362 { 363 int idx, err; 364 unsigned long offset = 0; 365 366 for (idx = 0; idx < BA1_MEMORY_COUNT; idx++) { 367 if ((err = snd_cs46xx_download(chip, 368 &BA1Struct.map[offset], 369 BA1Struct.memory[idx].offset, 370 BA1Struct.memory[idx].size)) < 0) 371 return err; 372 offset += BA1Struct.memory[idx].size >> 2; 373 } 374 return 0; 375 } 376 #endif /* CONFIG_SND_CS46XX_NEW_DSP */ 377 378 /* 379 * Chip reset 380 */ 381 382 static void snd_cs46xx_reset(cs46xx_t *chip) 383 { 384 int idx; 385 386 /* 387 * Write the reset bit of the SP control register. 388 */ 389 snd_cs46xx_poke(chip, BA1_SPCR, SPCR_RSTSP); 390 391 /* 392 * Write the control register. 393 */ 394 snd_cs46xx_poke(chip, BA1_SPCR, SPCR_DRQEN); 395 396 /* 397 * Clear the trap registers. 398 */ 399 for (idx = 0; idx < 8; idx++) { 400 snd_cs46xx_poke(chip, BA1_DREG, DREG_REGID_TRAP_SELECT + idx); 401 snd_cs46xx_poke(chip, BA1_TWPR, 0xFFFF); 402 } 403 snd_cs46xx_poke(chip, BA1_DREG, 0); 404 405 /* 406 * Set the frame timer to reflect the number of cycles per frame. 407 */ 408 snd_cs46xx_poke(chip, BA1_FRMT, 0xadf); 409 } 410 411 static int cs46xx_wait_for_fifo(cs46xx_t * chip,int retry_timeout) 412 { 413 u32 i, status = 0; 414 /* 415 * Make sure the previous FIFO write operation has completed. 416 */ 417 for(i = 0; i < 50; i++){ 418 status = snd_cs46xx_peekBA0(chip, BA0_SERBST); 419 420 if( !(status & SERBST_WBSY) ) 421 break; 422 423 mdelay(retry_timeout); 424 } 425 426 if(status & SERBST_WBSY) { 427 snd_printk( KERN_ERR "cs46xx: failure waiting for FIFO command to complete\n"); 428 429 return -EINVAL; 430 } 431 432 return 0; 433 } 434 435 static void snd_cs46xx_clear_serial_FIFOs(cs46xx_t *chip) 436 { 437 int idx, powerdown = 0; 438 unsigned int tmp; 439 440 /* 441 * See if the devices are powered down. If so, we must power them up first 442 * or they will not respond. 443 */ 444 tmp = snd_cs46xx_peekBA0(chip, BA0_CLKCR1); 445 if (!(tmp & CLKCR1_SWCE)) { 446 snd_cs46xx_pokeBA0(chip, BA0_CLKCR1, tmp | CLKCR1_SWCE); 447 powerdown = 1; 448 } 449 450 /* 451 * We want to clear out the serial port FIFOs so we don't end up playing 452 * whatever random garbage happens to be in them. We fill the sample FIFOS 453 * with zero (silence). 454 */ 455 snd_cs46xx_pokeBA0(chip, BA0_SERBWP, 0); 456 457 /* 458 * Fill all 256 sample FIFO locations. 459 */ 460 for (idx = 0; idx < 0xFF; idx++) { 461 /* 462 * Make sure the previous FIFO write operation has completed. 463 */ 464 if (cs46xx_wait_for_fifo(chip,1)) { 465 snd_printdd ("failed waiting for FIFO at addr (%02X)\n",idx); 466 467 if (powerdown) 468 snd_cs46xx_pokeBA0(chip, BA0_CLKCR1, tmp); 469 470 break; 471 } 472 /* 473 * Write the serial port FIFO index. 474 */ 475 snd_cs46xx_pokeBA0(chip, BA0_SERBAD, idx); 476 /* 477 * Tell the serial port to load the new value into the FIFO location. 478 */ 479 snd_cs46xx_pokeBA0(chip, BA0_SERBCM, SERBCM_WRC); 480 } 481 /* 482 * Now, if we powered up the devices, then power them back down again. 483 * This is kinda ugly, but should never happen. 484 */ 485 if (powerdown) 486 snd_cs46xx_pokeBA0(chip, BA0_CLKCR1, tmp); 487 } 488 489 static void snd_cs46xx_proc_start(cs46xx_t *chip) 490 { 491 int cnt; 492 493 /* 494 * Set the frame timer to reflect the number of cycles per frame. 495 */ 496 snd_cs46xx_poke(chip, BA1_FRMT, 0xadf); 497 /* 498 * Turn on the run, run at frame, and DMA enable bits in the local copy of 499 * the SP control register. 500 */ 501 snd_cs46xx_poke(chip, BA1_SPCR, SPCR_RUN | SPCR_RUNFR | SPCR_DRQEN); 502 /* 503 * Wait until the run at frame bit resets itself in the SP control 504 * register. 505 */ 506 for (cnt = 0; cnt < 25; cnt++) { 507 udelay(50); 508 if (!(snd_cs46xx_peek(chip, BA1_SPCR) & SPCR_RUNFR)) 509 break; 510 } 511 512 if (snd_cs46xx_peek(chip, BA1_SPCR) & SPCR_RUNFR) 513 snd_printk("SPCR_RUNFR never reset\n"); 514 } 515 516 static void snd_cs46xx_proc_stop(cs46xx_t *chip) 517 { 518 /* 519 * Turn off the run, run at frame, and DMA enable bits in the local copy of 520 * the SP control register. 521 */ 522 snd_cs46xx_poke(chip, BA1_SPCR, 0); 523 } 524 525 /* 526 * Sample rate routines 527 */ 528 529 #define GOF_PER_SEC 200 530 531 static void snd_cs46xx_set_play_sample_rate(cs46xx_t *chip, unsigned int rate) 532 { 533 unsigned long flags; 534 unsigned int tmp1, tmp2; 535 unsigned int phiIncr; 536 unsigned int correctionPerGOF, correctionPerSec; 537 538 /* 539 * Compute the values used to drive the actual sample rate conversion. 540 * The following formulas are being computed, using inline assembly 541 * since we need to use 64 bit arithmetic to compute the values: 542 * 543 * phiIncr = floor((Fs,in * 2^26) / Fs,out) 544 * correctionPerGOF = floor((Fs,in * 2^26 - Fs,out * phiIncr) / 545 * GOF_PER_SEC) 546 * ulCorrectionPerSec = Fs,in * 2^26 - Fs,out * phiIncr -M 547 * GOF_PER_SEC * correctionPerGOF 548 * 549 * i.e. 550 * 551 * phiIncr:other = dividend:remainder((Fs,in * 2^26) / Fs,out) 552 * correctionPerGOF:correctionPerSec = 553 * dividend:remainder(ulOther / GOF_PER_SEC) 554 */ 555 tmp1 = rate << 16; 556 phiIncr = tmp1 / 48000; 557 tmp1 -= phiIncr * 48000; 558 tmp1 <<= 10; 559 phiIncr <<= 10; 560 tmp2 = tmp1 / 48000; 561 phiIncr += tmp2; 562 tmp1 -= tmp2 * 48000; 563 correctionPerGOF = tmp1 / GOF_PER_SEC; 564 tmp1 -= correctionPerGOF * GOF_PER_SEC; 565 correctionPerSec = tmp1; 566 567 /* 568 * Fill in the SampleRateConverter control block. 569 */ 570 spin_lock_irqsave(&chip->reg_lock, flags); 571 snd_cs46xx_poke(chip, BA1_PSRC, 572 ((correctionPerSec << 16) & 0xFFFF0000) | (correctionPerGOF & 0xFFFF)); 573 snd_cs46xx_poke(chip, BA1_PPI, phiIncr); 574 spin_unlock_irqrestore(&chip->reg_lock, flags); 575 } 576 577 static void snd_cs46xx_set_capture_sample_rate(cs46xx_t *chip, unsigned int rate) 578 { 579 unsigned long flags; 580 unsigned int phiIncr, coeffIncr, tmp1, tmp2; 581 unsigned int correctionPerGOF, correctionPerSec, initialDelay; 582 unsigned int frameGroupLength, cnt; 583 584 /* 585 * We can only decimate by up to a factor of 1/9th the hardware rate. 586 * Correct the value if an attempt is made to stray outside that limit. 587 */ 588 if ((rate * 9) < 48000) 589 rate = 48000 / 9; 590 591 /* 592 * We can not capture at at rate greater than the Input Rate (48000). 593 * Return an error if an attempt is made to stray outside that limit. 594 */ 595 if (rate > 48000) 596 rate = 48000; 597 598 /* 599 * Compute the values used to drive the actual sample rate conversion. 600 * The following formulas are being computed, using inline assembly 601 * since we need to use 64 bit arithmetic to compute the values: 602 * 603 * coeffIncr = -floor((Fs,out * 2^23) / Fs,in) 604 * phiIncr = floor((Fs,in * 2^26) / Fs,out) 605 * correctionPerGOF = floor((Fs,in * 2^26 - Fs,out * phiIncr) / 606 * GOF_PER_SEC) 607 * correctionPerSec = Fs,in * 2^26 - Fs,out * phiIncr - 608 * GOF_PER_SEC * correctionPerGOF 609 * initialDelay = ceil((24 * Fs,in) / Fs,out) 610 * 611 * i.e. 612 * 613 * coeffIncr = neg(dividend((Fs,out * 2^23) / Fs,in)) 614 * phiIncr:ulOther = dividend:remainder((Fs,in * 2^26) / Fs,out) 615 * correctionPerGOF:correctionPerSec = 616 * dividend:remainder(ulOther / GOF_PER_SEC) 617 * initialDelay = dividend(((24 * Fs,in) + Fs,out - 1) / Fs,out) 618 */ 619 620 tmp1 = rate << 16; 621 coeffIncr = tmp1 / 48000; 622 tmp1 -= coeffIncr * 48000; 623 tmp1 <<= 7; 624 coeffIncr <<= 7; 625 coeffIncr += tmp1 / 48000; 626 coeffIncr ^= 0xFFFFFFFF; 627 coeffIncr++; 628 tmp1 = 48000 << 16; 629 phiIncr = tmp1 / rate; 630 tmp1 -= phiIncr * rate; 631 tmp1 <<= 10; 632 phiIncr <<= 10; 633 tmp2 = tmp1 / rate; 634 phiIncr += tmp2; 635 tmp1 -= tmp2 * rate; 636 correctionPerGOF = tmp1 / GOF_PER_SEC; 637 tmp1 -= correctionPerGOF * GOF_PER_SEC; 638 correctionPerSec = tmp1; 639 initialDelay = ((48000 * 24) + rate - 1) / rate; 640 641 /* 642 * Fill in the VariDecimate control block. 643 */ 644 spin_lock_irqsave(&chip->reg_lock, flags); 645 snd_cs46xx_poke(chip, BA1_CSRC, 646 ((correctionPerSec << 16) & 0xFFFF0000) | (correctionPerGOF & 0xFFFF)); 647 snd_cs46xx_poke(chip, BA1_CCI, coeffIncr); 648 snd_cs46xx_poke(chip, BA1_CD, 649 (((BA1_VARIDEC_BUF_1 + (initialDelay << 2)) << 16) & 0xFFFF0000) | 0x80); 650 snd_cs46xx_poke(chip, BA1_CPI, phiIncr); 651 spin_unlock_irqrestore(&chip->reg_lock, flags); 652 653 /* 654 * Figure out the frame group length for the write back task. Basically, 655 * this is just the factors of 24000 (2^6*3*5^3) that are not present in 656 * the output sample rate. 657 */ 658 frameGroupLength = 1; 659 for (cnt = 2; cnt <= 64; cnt *= 2) { 660 if (((rate / cnt) * cnt) != rate) 661 frameGroupLength *= 2; 662 } 663 if (((rate / 3) * 3) != rate) { 664 frameGroupLength *= 3; 665 } 666 for (cnt = 5; cnt <= 125; cnt *= 5) { 667 if (((rate / cnt) * cnt) != rate) 668 frameGroupLength *= 5; 669 } 670 671 /* 672 * Fill in the WriteBack control block. 673 */ 674 spin_lock_irqsave(&chip->reg_lock, flags); 675 snd_cs46xx_poke(chip, BA1_CFG1, frameGroupLength); 676 snd_cs46xx_poke(chip, BA1_CFG2, (0x00800000 | frameGroupLength)); 677 snd_cs46xx_poke(chip, BA1_CCST, 0x0000FFFF); 678 snd_cs46xx_poke(chip, BA1_CSPB, ((65536 * rate) / 24000)); 679 snd_cs46xx_poke(chip, (BA1_CSPB + 4), 0x0000FFFF); 680 spin_unlock_irqrestore(&chip->reg_lock, flags); 681 } 682 683 /* 684 * PCM part 685 */ 686 687 static void snd_cs46xx_pb_trans_copy(snd_pcm_substream_t *substream, 688 snd_pcm_indirect_t *rec, size_t bytes) 689 { 690 snd_pcm_runtime_t *runtime = substream->runtime; 691 cs46xx_pcm_t * cpcm = runtime->private_data; 692 memcpy(cpcm->hw_buf.area + rec->hw_data, runtime->dma_area + rec->sw_data, bytes); 693 } 694 695 static int snd_cs46xx_playback_transfer(snd_pcm_substream_t *substream) 696 { 697 snd_pcm_runtime_t *runtime = substream->runtime; 698 cs46xx_pcm_t * cpcm = runtime->private_data; 699 snd_pcm_indirect_playback_transfer(substream, &cpcm->pcm_rec, snd_cs46xx_pb_trans_copy); 700 return 0; 701 } 702 703 static void snd_cs46xx_cp_trans_copy(snd_pcm_substream_t *substream, 704 snd_pcm_indirect_t *rec, size_t bytes) 705 { 706 cs46xx_t *chip = snd_pcm_substream_chip(substream); 707 snd_pcm_runtime_t *runtime = substream->runtime; 708 memcpy(runtime->dma_area + rec->sw_data, 709 chip->capt.hw_buf.area + rec->hw_data, bytes); 710 } 711 712 static int snd_cs46xx_capture_transfer(snd_pcm_substream_t *substream) 713 { 714 cs46xx_t *chip = snd_pcm_substream_chip(substream); 715 snd_pcm_indirect_capture_transfer(substream, &chip->capt.pcm_rec, snd_cs46xx_cp_trans_copy); 716 return 0; 717 } 718 719 static snd_pcm_uframes_t snd_cs46xx_playback_direct_pointer(snd_pcm_substream_t * substream) 720 { 721 cs46xx_t *chip = snd_pcm_substream_chip(substream); 722 size_t ptr; 723 cs46xx_pcm_t *cpcm = substream->runtime->private_data; 724 snd_assert (cpcm->pcm_channel,return -ENXIO); 725 726 #ifdef CONFIG_SND_CS46XX_NEW_DSP 727 ptr = snd_cs46xx_peek(chip, (cpcm->pcm_channel->pcm_reader_scb->address + 2) << 2); 728 #else 729 ptr = snd_cs46xx_peek(chip, BA1_PBA); 730 #endif 731 ptr -= cpcm->hw_buf.addr; 732 return ptr >> cpcm->shift; 733 } 734 735 static snd_pcm_uframes_t snd_cs46xx_playback_indirect_pointer(snd_pcm_substream_t * substream) 736 { 737 cs46xx_t *chip = snd_pcm_substream_chip(substream); 738 size_t ptr; 739 cs46xx_pcm_t *cpcm = substream->runtime->private_data; 740 741 #ifdef CONFIG_SND_CS46XX_NEW_DSP 742 snd_assert (cpcm->pcm_channel,return -ENXIO); 743 ptr = snd_cs46xx_peek(chip, (cpcm->pcm_channel->pcm_reader_scb->address + 2) << 2); 744 #else 745 ptr = snd_cs46xx_peek(chip, BA1_PBA); 746 #endif 747 ptr -= cpcm->hw_buf.addr; 748 return snd_pcm_indirect_playback_pointer(substream, &cpcm->pcm_rec, ptr); 749 } 750 751 static snd_pcm_uframes_t snd_cs46xx_capture_direct_pointer(snd_pcm_substream_t * substream) 752 { 753 cs46xx_t *chip = snd_pcm_substream_chip(substream); 754 size_t ptr = snd_cs46xx_peek(chip, BA1_CBA) - chip->capt.hw_buf.addr; 755 return ptr >> chip->capt.shift; 756 } 757 758 static snd_pcm_uframes_t snd_cs46xx_capture_indirect_pointer(snd_pcm_substream_t * substream) 759 { 760 cs46xx_t *chip = snd_pcm_substream_chip(substream); 761 size_t ptr = snd_cs46xx_peek(chip, BA1_CBA) - chip->capt.hw_buf.addr; 762 return snd_pcm_indirect_capture_pointer(substream, &chip->capt.pcm_rec, ptr); 763 } 764 765 static int snd_cs46xx_playback_trigger(snd_pcm_substream_t * substream, 766 int cmd) 767 { 768 cs46xx_t *chip = snd_pcm_substream_chip(substream); 769 /*snd_pcm_runtime_t *runtime = substream->runtime;*/ 770 int result = 0; 771 772 #ifdef CONFIG_SND_CS46XX_NEW_DSP 773 cs46xx_pcm_t *cpcm = substream->runtime->private_data; 774 if (! cpcm->pcm_channel) { 775 return -ENXIO; 776 } 777 #endif 778 switch (cmd) { 779 case SNDRV_PCM_TRIGGER_START: 780 case SNDRV_PCM_TRIGGER_RESUME: 781 #ifdef CONFIG_SND_CS46XX_NEW_DSP 782 /* magic value to unmute PCM stream playback volume */ 783 snd_cs46xx_poke(chip, (cpcm->pcm_channel->pcm_reader_scb->address + 784 SCBVolumeCtrl) << 2, 0x80008000); 785 786 if (cpcm->pcm_channel->unlinked) 787 cs46xx_dsp_pcm_link(chip,cpcm->pcm_channel); 788 789 if (substream->runtime->periods != CS46XX_FRAGS) 790 snd_cs46xx_playback_transfer(substream); 791 #else 792 spin_lock(&chip->reg_lock); 793 if (substream->runtime->periods != CS46XX_FRAGS) 794 snd_cs46xx_playback_transfer(substream); 795 { unsigned int tmp; 796 tmp = snd_cs46xx_peek(chip, BA1_PCTL); 797 tmp &= 0x0000ffff; 798 snd_cs46xx_poke(chip, BA1_PCTL, chip->play_ctl | tmp); 799 } 800 spin_unlock(&chip->reg_lock); 801 #endif 802 break; 803 case SNDRV_PCM_TRIGGER_STOP: 804 case SNDRV_PCM_TRIGGER_SUSPEND: 805 #ifdef CONFIG_SND_CS46XX_NEW_DSP 806 /* magic mute channel */ 807 snd_cs46xx_poke(chip, (cpcm->pcm_channel->pcm_reader_scb->address + 808 SCBVolumeCtrl) << 2, 0xffffffff); 809 810 if (!cpcm->pcm_channel->unlinked) 811 cs46xx_dsp_pcm_unlink(chip,cpcm->pcm_channel); 812 #else 813 spin_lock(&chip->reg_lock); 814 { unsigned int tmp; 815 tmp = snd_cs46xx_peek(chip, BA1_PCTL); 816 tmp &= 0x0000ffff; 817 snd_cs46xx_poke(chip, BA1_PCTL, tmp); 818 } 819 spin_unlock(&chip->reg_lock); 820 #endif 821 break; 822 default: 823 result = -EINVAL; 824 break; 825 } 826 827 return result; 828 } 829 830 static int snd_cs46xx_capture_trigger(snd_pcm_substream_t * substream, 831 int cmd) 832 { 833 cs46xx_t *chip = snd_pcm_substream_chip(substream); 834 unsigned int tmp; 835 int result = 0; 836 837 spin_lock(&chip->reg_lock); 838 switch (cmd) { 839 case SNDRV_PCM_TRIGGER_START: 840 case SNDRV_PCM_TRIGGER_RESUME: 841 tmp = snd_cs46xx_peek(chip, BA1_CCTL); 842 tmp &= 0xffff0000; 843 snd_cs46xx_poke(chip, BA1_CCTL, chip->capt.ctl | tmp); 844 break; 845 case SNDRV_PCM_TRIGGER_STOP: 846 case SNDRV_PCM_TRIGGER_SUSPEND: 847 tmp = snd_cs46xx_peek(chip, BA1_CCTL); 848 tmp &= 0xffff0000; 849 snd_cs46xx_poke(chip, BA1_CCTL, tmp); 850 break; 851 default: 852 result = -EINVAL; 853 break; 854 } 855 spin_unlock(&chip->reg_lock); 856 857 return result; 858 } 859 860 #ifdef CONFIG_SND_CS46XX_NEW_DSP 861 static int _cs46xx_adjust_sample_rate (cs46xx_t *chip, cs46xx_pcm_t *cpcm, 862 int sample_rate) 863 { 864 865 /* If PCMReaderSCB and SrcTaskSCB not created yet ... */ 866 if ( cpcm->pcm_channel == NULL) { 867 cpcm->pcm_channel = cs46xx_dsp_create_pcm_channel (chip, sample_rate, 868 cpcm, cpcm->hw_buf.addr,cpcm->pcm_channel_id); 869 if (cpcm->pcm_channel == NULL) { 870 snd_printk(KERN_ERR "cs46xx: failed to create virtual PCM channel\n"); 871 return -ENOMEM; 872 } 873 cpcm->pcm_channel->sample_rate = sample_rate; 874 } else 875 /* if sample rate is changed */ 876 if ((int)cpcm->pcm_channel->sample_rate != sample_rate) { 877 int unlinked = cpcm->pcm_channel->unlinked; 878 cs46xx_dsp_destroy_pcm_channel (chip,cpcm->pcm_channel); 879 880 if ( (cpcm->pcm_channel = cs46xx_dsp_create_pcm_channel (chip, sample_rate, cpcm, 881 cpcm->hw_buf.addr, 882 cpcm->pcm_channel_id)) == NULL) { 883 snd_printk(KERN_ERR "cs46xx: failed to re-create virtual PCM channel\n"); 884 return -ENOMEM; 885 } 886 887 if (!unlinked) cs46xx_dsp_pcm_link (chip,cpcm->pcm_channel); 888 cpcm->pcm_channel->sample_rate = sample_rate; 889 } 890 891 return 0; 892 } 893 #endif 894 895 896 static int snd_cs46xx_playback_hw_params(snd_pcm_substream_t * substream, 897 snd_pcm_hw_params_t * hw_params) 898 { 899 snd_pcm_runtime_t *runtime = substream->runtime; 900 cs46xx_pcm_t *cpcm; 901 int err; 902 #ifdef CONFIG_SND_CS46XX_NEW_DSP 903 cs46xx_t *chip = snd_pcm_substream_chip(substream); 904 int sample_rate = params_rate(hw_params); 905 int period_size = params_period_bytes(hw_params); 906 #endif 907 cpcm = runtime->private_data; 908 909 #ifdef CONFIG_SND_CS46XX_NEW_DSP 910 snd_assert (sample_rate != 0, return -ENXIO); 911 912 down (&chip->spos_mutex); 913 914 if (_cs46xx_adjust_sample_rate (chip,cpcm,sample_rate)) { 915 up (&chip->spos_mutex); 916 return -ENXIO; 917 } 918 919 snd_assert (cpcm->pcm_channel != NULL); 920 if (!cpcm->pcm_channel) { 921 up (&chip->spos_mutex); 922 return -ENXIO; 923 } 924 925 926 if (cs46xx_dsp_pcm_channel_set_period (chip,cpcm->pcm_channel,period_size)) { 927 up (&chip->spos_mutex); 928 return -EINVAL; 929 } 930 931 snd_printdd ("period_size (%d), periods (%d) buffer_size(%d)\n", 932 period_size, params_periods(hw_params), 933 params_buffer_bytes(hw_params)); 934 #endif 935 936 if (params_periods(hw_params) == CS46XX_FRAGS) { 937 if (runtime->dma_area != cpcm->hw_buf.area) 938 snd_pcm_lib_free_pages(substream); 939 runtime->dma_area = cpcm->hw_buf.area; 940 runtime->dma_addr = cpcm->hw_buf.addr; 941 runtime->dma_bytes = cpcm->hw_buf.bytes; 942 943 944 #ifdef CONFIG_SND_CS46XX_NEW_DSP 945 if (cpcm->pcm_channel_id == DSP_PCM_MAIN_CHANNEL) { 946 substream->ops = &snd_cs46xx_playback_ops; 947 } else if (cpcm->pcm_channel_id == DSP_PCM_REAR_CHANNEL) { 948 substream->ops = &snd_cs46xx_playback_rear_ops; 949 } else if (cpcm->pcm_channel_id == DSP_PCM_CENTER_LFE_CHANNEL) { 950 substream->ops = &snd_cs46xx_playback_clfe_ops; 951 } else if (cpcm->pcm_channel_id == DSP_IEC958_CHANNEL) { 952 substream->ops = &snd_cs46xx_playback_iec958_ops; 953 } else { 954 snd_assert(0); 955 } 956 #else 957 substream->ops = &snd_cs46xx_playback_ops; 958 #endif 959 960 } else { 961 if (runtime->dma_area == cpcm->hw_buf.area) { 962 runtime->dma_area = NULL; 963 runtime->dma_addr = 0; 964 runtime->dma_bytes = 0; 965 } 966 if ((err = snd_pcm_lib_malloc_pages(substream, params_buffer_bytes(hw_params))) < 0) { 967 #ifdef CONFIG_SND_CS46XX_NEW_DSP 968 up (&chip->spos_mutex); 969 #endif 970 return err; 971 } 972 973 #ifdef CONFIG_SND_CS46XX_NEW_DSP 974 if (cpcm->pcm_channel_id == DSP_PCM_MAIN_CHANNEL) { 975 substream->ops = &snd_cs46xx_playback_indirect_ops; 976 } else if (cpcm->pcm_channel_id == DSP_PCM_REAR_CHANNEL) { 977 substream->ops = &snd_cs46xx_playback_indirect_rear_ops; 978 } else if (cpcm->pcm_channel_id == DSP_PCM_CENTER_LFE_CHANNEL) { 979 substream->ops = &snd_cs46xx_playback_indirect_clfe_ops; 980 } else if (cpcm->pcm_channel_id == DSP_IEC958_CHANNEL) { 981 substream->ops = &snd_cs46xx_playback_indirect_iec958_ops; 982 } else { 983 snd_assert(0); 984 } 985 #else 986 substream->ops = &snd_cs46xx_playback_indirect_ops; 987 #endif 988 989 } 990 991 #ifdef CONFIG_SND_CS46XX_NEW_DSP 992 up (&chip->spos_mutex); 993 #endif 994 995 return 0; 996 } 997 998 static int snd_cs46xx_playback_hw_free(snd_pcm_substream_t * substream) 999 { 1000 /*cs46xx_t *chip = snd_pcm_substream_chip(substream);*/ 1001 snd_pcm_runtime_t *runtime = substream->runtime; 1002 cs46xx_pcm_t *cpcm; 1003 1004 cpcm = runtime->private_data; 1005 1006 /* if play_back open fails, then this function 1007 is called and cpcm can actually be NULL here */ 1008 if (!cpcm) return -ENXIO; 1009 1010 if (runtime->dma_area != cpcm->hw_buf.area) 1011 snd_pcm_lib_free_pages(substream); 1012 1013 runtime->dma_area = NULL; 1014 runtime->dma_addr = 0; 1015 runtime->dma_bytes = 0; 1016 1017 return 0; 1018 } 1019 1020 static int snd_cs46xx_playback_prepare(snd_pcm_substream_t * substream) 1021 { 1022 unsigned int tmp; 1023 unsigned int pfie; 1024 cs46xx_t *chip = snd_pcm_substream_chip(substream); 1025 snd_pcm_runtime_t *runtime = substream->runtime; 1026 cs46xx_pcm_t *cpcm; 1027 1028 cpcm = runtime->private_data; 1029 1030 #ifdef CONFIG_SND_CS46XX_NEW_DSP 1031 snd_assert (cpcm->pcm_channel != NULL, return -ENXIO); 1032 1033 pfie = snd_cs46xx_peek(chip, (cpcm->pcm_channel->pcm_reader_scb->address + 1) << 2 ); 1034 pfie &= ~0x0000f03f; 1035 #else 1036 /* old dsp */ 1037 pfie = snd_cs46xx_peek(chip, BA1_PFIE); 1038 pfie &= ~0x0000f03f; 1039 #endif 1040 1041 cpcm->shift = 2; 1042 /* if to convert from stereo to mono */ 1043 if (runtime->channels == 1) { 1044 cpcm->shift--; 1045 pfie |= 0x00002000; 1046 } 1047 /* if to convert from 8 bit to 16 bit */ 1048 if (snd_pcm_format_width(runtime->format) == 8) { 1049 cpcm->shift--; 1050 pfie |= 0x00001000; 1051 } 1052 /* if to convert to unsigned */ 1053 if (snd_pcm_format_unsigned(runtime->format)) 1054 pfie |= 0x00008000; 1055 1056 /* Never convert byte order when sample stream is 8 bit */ 1057 if (snd_pcm_format_width(runtime->format) != 8) { 1058 /* convert from big endian to little endian */ 1059 if (snd_pcm_format_big_endian(runtime->format)) 1060 pfie |= 0x00004000; 1061 } 1062 1063 memset(&cpcm->pcm_rec, 0, sizeof(cpcm->pcm_rec)); 1064 cpcm->pcm_rec.sw_buffer_size = snd_pcm_lib_buffer_bytes(substream); 1065 cpcm->pcm_rec.hw_buffer_size = runtime->period_size * CS46XX_FRAGS << cpcm->shift; 1066 1067 #ifdef CONFIG_SND_CS46XX_NEW_DSP 1068 1069 tmp = snd_cs46xx_peek(chip, (cpcm->pcm_channel->pcm_reader_scb->address) << 2); 1070 tmp &= ~0x000003ff; 1071 tmp |= (4 << cpcm->shift) - 1; 1072 /* playback transaction count register */ 1073 snd_cs46xx_poke(chip, (cpcm->pcm_channel->pcm_reader_scb->address) << 2, tmp); 1074 1075 /* playback format && interrupt enable */ 1076 snd_cs46xx_poke(chip, (cpcm->pcm_channel->pcm_reader_scb->address + 1) << 2, pfie | cpcm->pcm_channel->pcm_slot); 1077 #else 1078 snd_cs46xx_poke(chip, BA1_PBA, cpcm->hw_buf.addr); 1079 tmp = snd_cs46xx_peek(chip, BA1_PDTC); 1080 tmp &= ~0x000003ff; 1081 tmp |= (4 << cpcm->shift) - 1; 1082 snd_cs46xx_poke(chip, BA1_PDTC, tmp); 1083 snd_cs46xx_poke(chip, BA1_PFIE, pfie); 1084 snd_cs46xx_set_play_sample_rate(chip, runtime->rate); 1085 #endif 1086 1087 return 0; 1088 } 1089 1090 static int snd_cs46xx_capture_hw_params(snd_pcm_substream_t * substream, 1091 snd_pcm_hw_params_t * hw_params) 1092 { 1093 cs46xx_t *chip = snd_pcm_substream_chip(substream); 1094 snd_pcm_runtime_t *runtime = substream->runtime; 1095 int err; 1096 1097 #ifdef CONFIG_SND_CS46XX_NEW_DSP 1098 cs46xx_dsp_pcm_ostream_set_period (chip, params_period_bytes(hw_params)); 1099 #endif 1100 if (runtime->periods == CS46XX_FRAGS) { 1101 if (runtime->dma_area != chip->capt.hw_buf.area) 1102 snd_pcm_lib_free_pages(substream); 1103 runtime->dma_area = chip->capt.hw_buf.area; 1104 runtime->dma_addr = chip->capt.hw_buf.addr; 1105 runtime->dma_bytes = chip->capt.hw_buf.bytes; 1106 substream->ops = &snd_cs46xx_capture_ops; 1107 } else { 1108 if (runtime->dma_area == chip->capt.hw_buf.area) { 1109 runtime->dma_area = NULL; 1110 runtime->dma_addr = 0; 1111 runtime->dma_bytes = 0; 1112 } 1113 if ((err = snd_pcm_lib_malloc_pages(substream, params_buffer_bytes(hw_params))) < 0) 1114 return err; 1115 substream->ops = &snd_cs46xx_capture_indirect_ops; 1116 } 1117 1118 return 0; 1119 } 1120 1121 static int snd_cs46xx_capture_hw_free(snd_pcm_substream_t * substream) 1122 { 1123 cs46xx_t *chip = snd_pcm_substream_chip(substream); 1124 snd_pcm_runtime_t *runtime = substream->runtime; 1125 1126 if (runtime->dma_area != chip->capt.hw_buf.area) 1127 snd_pcm_lib_free_pages(substream); 1128 runtime->dma_area = NULL; 1129 runtime->dma_addr = 0; 1130 runtime->dma_bytes = 0; 1131 1132 return 0; 1133 } 1134 1135 static int snd_cs46xx_capture_prepare(snd_pcm_substream_t * substream) 1136 { 1137 cs46xx_t *chip = snd_pcm_substream_chip(substream); 1138 snd_pcm_runtime_t *runtime = substream->runtime; 1139 1140 snd_cs46xx_poke(chip, BA1_CBA, chip->capt.hw_buf.addr); 1141 chip->capt.shift = 2; 1142 memset(&chip->capt.pcm_rec, 0, sizeof(chip->capt.pcm_rec)); 1143 chip->capt.pcm_rec.sw_buffer_size = snd_pcm_lib_buffer_bytes(substream); 1144 chip->capt.pcm_rec.hw_buffer_size = runtime->period_size * CS46XX_FRAGS << 2; 1145 snd_cs46xx_set_capture_sample_rate(chip, runtime->rate); 1146 1147 return 0; 1148 } 1149 1150 static irqreturn_t snd_cs46xx_interrupt(int irq, void *dev_id, struct pt_regs *regs) 1151 { 1152 cs46xx_t *chip = dev_id; 1153 u32 status1; 1154 #ifdef CONFIG_SND_CS46XX_NEW_DSP 1155 dsp_spos_instance_t * ins = chip->dsp_spos_instance; 1156 u32 status2; 1157 int i; 1158 cs46xx_pcm_t *cpcm = NULL; 1159 #endif 1160 1161 /* 1162 * Read the Interrupt Status Register to clear the interrupt 1163 */ 1164 status1 = snd_cs46xx_peekBA0(chip, BA0_HISR); 1165 if ((status1 & 0x7fffffff) == 0) { 1166 snd_cs46xx_pokeBA0(chip, BA0_HICR, HICR_CHGM | HICR_IEV); 1167 return IRQ_NONE; 1168 } 1169 1170 #ifdef CONFIG_SND_CS46XX_NEW_DSP 1171 status2 = snd_cs46xx_peekBA0(chip, BA0_HSR0); 1172 1173 for (i = 0; i < DSP_MAX_PCM_CHANNELS; ++i) { 1174 if (i <= 15) { 1175 if ( status1 & (1 << i) ) { 1176 if (i == CS46XX_DSP_CAPTURE_CHANNEL) { 1177 if (chip->capt.substream) 1178 snd_pcm_period_elapsed(chip->capt.substream); 1179 } else { 1180 if (ins->pcm_channels[i].active && 1181 ins->pcm_channels[i].private_data && 1182 !ins->pcm_channels[i].unlinked) { 1183 cpcm = ins->pcm_channels[i].private_data; 1184 snd_pcm_period_elapsed(cpcm->substream); 1185 } 1186 } 1187 } 1188 } else { 1189 if ( status2 & (1 << (i - 16))) { 1190 if (ins->pcm_channels[i].active && 1191 ins->pcm_channels[i].private_data && 1192 !ins->pcm_channels[i].unlinked) { 1193 cpcm = ins->pcm_channels[i].private_data; 1194 snd_pcm_period_elapsed(cpcm->substream); 1195 } 1196 } 1197 } 1198 } 1199 1200 #else 1201 /* old dsp */ 1202 if ((status1 & HISR_VC0) && chip->playback_pcm) { 1203 if (chip->playback_pcm->substream) 1204 snd_pcm_period_elapsed(chip->playback_pcm->substream); 1205 } 1206 if ((status1 & HISR_VC1) && chip->pcm) { 1207 if (chip->capt.substream) 1208 snd_pcm_period_elapsed(chip->capt.substream); 1209 } 1210 #endif 1211 1212 if ((status1 & HISR_MIDI) && chip->rmidi) { 1213 unsigned char c; 1214 1215 spin_lock(&chip->reg_lock); 1216 while ((snd_cs46xx_peekBA0(chip, BA0_MIDSR) & MIDSR_RBE) == 0) { 1217 c = snd_cs46xx_peekBA0(chip, BA0_MIDRP); 1218 if ((chip->midcr & MIDCR_RIE) == 0) 1219 continue; 1220 snd_rawmidi_receive(chip->midi_input, &c, 1); 1221 } 1222 while ((snd_cs46xx_peekBA0(chip, BA0_MIDSR) & MIDSR_TBF) == 0) { 1223 if ((chip->midcr & MIDCR_TIE) == 0) 1224 break; 1225 if (snd_rawmidi_transmit(chip->midi_output, &c, 1) != 1) { 1226 chip->midcr &= ~MIDCR_TIE; 1227 snd_cs46xx_pokeBA0(chip, BA0_MIDCR, chip->midcr); 1228 break; 1229 } 1230 snd_cs46xx_pokeBA0(chip, BA0_MIDWP, c); 1231 } 1232 spin_unlock(&chip->reg_lock); 1233 } 1234 /* 1235 * EOI to the PCI part....reenables interrupts 1236 */ 1237 snd_cs46xx_pokeBA0(chip, BA0_HICR, HICR_CHGM | HICR_IEV); 1238 1239 return IRQ_HANDLED; 1240 } 1241 1242 static snd_pcm_hardware_t snd_cs46xx_playback = 1243 { 1244 .info = (SNDRV_PCM_INFO_MMAP | 1245 SNDRV_PCM_INFO_INTERLEAVED | 1246 SNDRV_PCM_INFO_BLOCK_TRANSFER /*|*/ 1247 /*SNDRV_PCM_INFO_RESUME*/), 1248 .formats = (SNDRV_PCM_FMTBIT_S8 | SNDRV_PCM_FMTBIT_U8 | 1249 SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S16_BE | 1250 SNDRV_PCM_FMTBIT_U16_LE | SNDRV_PCM_FMTBIT_U16_BE), 1251 .rates = SNDRV_PCM_RATE_CONTINUOUS | SNDRV_PCM_RATE_8000_48000, 1252 .rate_min = 5500, 1253 .rate_max = 48000, 1254 .channels_min = 1, 1255 .channels_max = 2, 1256 .buffer_bytes_max = (256 * 1024), 1257 .period_bytes_min = CS46XX_MIN_PERIOD_SIZE, 1258 .period_bytes_max = CS46XX_MAX_PERIOD_SIZE, 1259 .periods_min = CS46XX_FRAGS, 1260 .periods_max = 1024, 1261 .fifo_size = 0, 1262 }; 1263 1264 static snd_pcm_hardware_t snd_cs46xx_capture = 1265 { 1266 .info = (SNDRV_PCM_INFO_MMAP | 1267 SNDRV_PCM_INFO_INTERLEAVED | 1268 SNDRV_PCM_INFO_BLOCK_TRANSFER /*|*/ 1269 /*SNDRV_PCM_INFO_RESUME*/), 1270 .formats = SNDRV_PCM_FMTBIT_S16_LE, 1271 .rates = SNDRV_PCM_RATE_CONTINUOUS | SNDRV_PCM_RATE_8000_48000, 1272 .rate_min = 5500, 1273 .rate_max = 48000, 1274 .channels_min = 2, 1275 .channels_max = 2, 1276 .buffer_bytes_max = (256 * 1024), 1277 .period_bytes_min = CS46XX_MIN_PERIOD_SIZE, 1278 .period_bytes_max = CS46XX_MAX_PERIOD_SIZE, 1279 .periods_min = CS46XX_FRAGS, 1280 .periods_max = 1024, 1281 .fifo_size = 0, 1282 }; 1283 1284 #ifdef CONFIG_SND_CS46XX_NEW_DSP 1285 1286 static unsigned int period_sizes[] = { 32, 64, 128, 256, 512, 1024, 2048 }; 1287 1288 static snd_pcm_hw_constraint_list_t hw_constraints_period_sizes = { 1289 .count = ARRAY_SIZE(period_sizes), 1290 .list = period_sizes, 1291 .mask = 0 1292 }; 1293 1294 #endif 1295 1296 static void snd_cs46xx_pcm_free_substream(snd_pcm_runtime_t *runtime) 1297 { 1298 kfree(runtime->private_data); 1299 } 1300 1301 static int _cs46xx_playback_open_channel (snd_pcm_substream_t * substream,int pcm_channel_id) 1302 { 1303 cs46xx_t *chip = snd_pcm_substream_chip(substream); 1304 cs46xx_pcm_t * cpcm; 1305 snd_pcm_runtime_t *runtime = substream->runtime; 1306 1307 cpcm = kcalloc(1, sizeof(*cpcm), GFP_KERNEL); 1308 if (cpcm == NULL) 1309 return -ENOMEM; 1310 if (snd_dma_alloc_pages(SNDRV_DMA_TYPE_DEV, snd_dma_pci_data(chip->pci), 1311 PAGE_SIZE, &cpcm->hw_buf) < 0) { 1312 kfree(cpcm); 1313 return -ENOMEM; 1314 } 1315 1316 runtime->hw = snd_cs46xx_playback; 1317 runtime->private_data = cpcm; 1318 runtime->private_free = snd_cs46xx_pcm_free_substream; 1319 1320 cpcm->substream = substream; 1321 #ifdef CONFIG_SND_CS46XX_NEW_DSP 1322 down (&chip->spos_mutex); 1323 cpcm->pcm_channel = NULL; 1324 cpcm->pcm_channel_id = pcm_channel_id; 1325 1326 1327 snd_pcm_hw_constraint_list(runtime, 0, 1328 SNDRV_PCM_HW_PARAM_PERIOD_BYTES, 1329 &hw_constraints_period_sizes); 1330 1331 up (&chip->spos_mutex); 1332 #else 1333 chip->playback_pcm = cpcm; /* HACK */ 1334 #endif 1335 1336 if (chip->accept_valid) 1337 substream->runtime->hw.info |= SNDRV_PCM_INFO_MMAP_VALID; 1338 chip->active_ctrl(chip, 1); 1339 1340 return 0; 1341 } 1342 1343 static int snd_cs46xx_playback_open(snd_pcm_substream_t * substream) 1344 { 1345 snd_printdd("open front channel\n"); 1346 return _cs46xx_playback_open_channel(substream,DSP_PCM_MAIN_CHANNEL); 1347 } 1348 1349 #ifdef CONFIG_SND_CS46XX_NEW_DSP 1350 static int snd_cs46xx_playback_open_rear(snd_pcm_substream_t * substream) 1351 { 1352 snd_printdd("open rear channel\n"); 1353 1354 return _cs46xx_playback_open_channel(substream,DSP_PCM_REAR_CHANNEL); 1355 } 1356 1357 static int snd_cs46xx_playback_open_clfe(snd_pcm_substream_t * substream) 1358 { 1359 snd_printdd("open center - LFE channel\n"); 1360 1361 return _cs46xx_playback_open_channel(substream,DSP_PCM_CENTER_LFE_CHANNEL); 1362 } 1363 1364 static int snd_cs46xx_playback_open_iec958(snd_pcm_substream_t * substream) 1365 { 1366 cs46xx_t *chip = snd_pcm_substream_chip(substream); 1367 1368 snd_printdd("open raw iec958 channel\n"); 1369 1370 down (&chip->spos_mutex); 1371 cs46xx_iec958_pre_open (chip); 1372 up (&chip->spos_mutex); 1373 1374 return _cs46xx_playback_open_channel(substream,DSP_IEC958_CHANNEL); 1375 } 1376 1377 static int snd_cs46xx_playback_close(snd_pcm_substream_t * substream); 1378 1379 static int snd_cs46xx_playback_close_iec958(snd_pcm_substream_t * substream) 1380 { 1381 int err; 1382 cs46xx_t *chip = snd_pcm_substream_chip(substream); 1383 1384 snd_printdd("close raw iec958 channel\n"); 1385 1386 err = snd_cs46xx_playback_close(substream); 1387 1388 down (&chip->spos_mutex); 1389 cs46xx_iec958_post_close (chip); 1390 up (&chip->spos_mutex); 1391 1392 return err; 1393 } 1394 #endif 1395 1396 static int snd_cs46xx_capture_open(snd_pcm_substream_t * substream) 1397 { 1398 cs46xx_t *chip = snd_pcm_substream_chip(substream); 1399 1400 if (snd_dma_alloc_pages(SNDRV_DMA_TYPE_DEV, snd_dma_pci_data(chip->pci), 1401 PAGE_SIZE, &chip->capt.hw_buf) < 0) 1402 return -ENOMEM; 1403 chip->capt.substream = substream; 1404 substream->runtime->hw = snd_cs46xx_capture; 1405 1406 if (chip->accept_valid) 1407 substream->runtime->hw.info |= SNDRV_PCM_INFO_MMAP_VALID; 1408 1409 chip->active_ctrl(chip, 1); 1410 1411 #ifdef CONFIG_SND_CS46XX_NEW_DSP 1412 snd_pcm_hw_constraint_list(substream->runtime, 0, 1413 SNDRV_PCM_HW_PARAM_PERIOD_BYTES, 1414 &hw_constraints_period_sizes); 1415 #endif 1416 return 0; 1417 } 1418 1419 static int snd_cs46xx_playback_close(snd_pcm_substream_t * substream) 1420 { 1421 cs46xx_t *chip = snd_pcm_substream_chip(substream); 1422 snd_pcm_runtime_t *runtime = substream->runtime; 1423 cs46xx_pcm_t * cpcm; 1424 1425 cpcm = runtime->private_data; 1426 1427 /* when playback_open fails, then cpcm can be NULL */ 1428 if (!cpcm) return -ENXIO; 1429 1430 #ifdef CONFIG_SND_CS46XX_NEW_DSP 1431 down (&chip->spos_mutex); 1432 if (cpcm->pcm_channel) { 1433 cs46xx_dsp_destroy_pcm_channel(chip,cpcm->pcm_channel); 1434 cpcm->pcm_channel = NULL; 1435 } 1436 up (&chip->spos_mutex); 1437 #else 1438 chip->playback_pcm = NULL; 1439 #endif 1440 1441 cpcm->substream = NULL; 1442 snd_dma_free_pages(&cpcm->hw_buf); 1443 chip->active_ctrl(chip, -1); 1444 1445 return 0; 1446 } 1447 1448 static int snd_cs46xx_capture_close(snd_pcm_substream_t * substream) 1449 { 1450 cs46xx_t *chip = snd_pcm_substream_chip(substream); 1451 1452 chip->capt.substream = NULL; 1453 snd_dma_free_pages(&chip->capt.hw_buf); 1454 chip->active_ctrl(chip, -1); 1455 1456 return 0; 1457 } 1458 1459 #ifdef CONFIG_SND_CS46XX_NEW_DSP 1460 static snd_pcm_ops_t snd_cs46xx_playback_rear_ops = { 1461 .open = snd_cs46xx_playback_open_rear, 1462 .close = snd_cs46xx_playback_close, 1463 .ioctl = snd_pcm_lib_ioctl, 1464 .hw_params = snd_cs46xx_playback_hw_params, 1465 .hw_free = snd_cs46xx_playback_hw_free, 1466 .prepare = snd_cs46xx_playback_prepare, 1467 .trigger = snd_cs46xx_playback_trigger, 1468 .pointer = snd_cs46xx_playback_direct_pointer, 1469 }; 1470 1471 static snd_pcm_ops_t snd_cs46xx_playback_indirect_rear_ops = { 1472 .open = snd_cs46xx_playback_open_rear, 1473 .close = snd_cs46xx_playback_close, 1474 .ioctl = snd_pcm_lib_ioctl, 1475 .hw_params = snd_cs46xx_playback_hw_params, 1476 .hw_free = snd_cs46xx_playback_hw_free, 1477 .prepare = snd_cs46xx_playback_prepare, 1478 .trigger = snd_cs46xx_playback_trigger, 1479 .pointer = snd_cs46xx_playback_indirect_pointer, 1480 .ack = snd_cs46xx_playback_transfer, 1481 }; 1482 1483 static snd_pcm_ops_t snd_cs46xx_playback_clfe_ops = { 1484 .open = snd_cs46xx_playback_open_clfe, 1485 .close = snd_cs46xx_playback_close, 1486 .ioctl = snd_pcm_lib_ioctl, 1487 .hw_params = snd_cs46xx_playback_hw_params, 1488 .hw_free = snd_cs46xx_playback_hw_free, 1489 .prepare = snd_cs46xx_playback_prepare, 1490 .trigger = snd_cs46xx_playback_trigger, 1491 .pointer = snd_cs46xx_playback_direct_pointer, 1492 }; 1493 1494 static snd_pcm_ops_t snd_cs46xx_playback_indirect_clfe_ops = { 1495 .open = snd_cs46xx_playback_open_clfe, 1496 .close = snd_cs46xx_playback_close, 1497 .ioctl = snd_pcm_lib_ioctl, 1498 .hw_params = snd_cs46xx_playback_hw_params, 1499 .hw_free = snd_cs46xx_playback_hw_free, 1500 .prepare = snd_cs46xx_playback_prepare, 1501 .trigger = snd_cs46xx_playback_trigger, 1502 .pointer = snd_cs46xx_playback_indirect_pointer, 1503 .ack = snd_cs46xx_playback_transfer, 1504 }; 1505 1506 static snd_pcm_ops_t snd_cs46xx_playback_iec958_ops = { 1507 .open = snd_cs46xx_playback_open_iec958, 1508 .close = snd_cs46xx_playback_close_iec958, 1509 .ioctl = snd_pcm_lib_ioctl, 1510 .hw_params = snd_cs46xx_playback_hw_params, 1511 .hw_free = snd_cs46xx_playback_hw_free, 1512 .prepare = snd_cs46xx_playback_prepare, 1513 .trigger = snd_cs46xx_playback_trigger, 1514 .pointer = snd_cs46xx_playback_direct_pointer, 1515 }; 1516 1517 static snd_pcm_ops_t snd_cs46xx_playback_indirect_iec958_ops = { 1518 .open = snd_cs46xx_playback_open_iec958, 1519 .close = snd_cs46xx_playback_close_iec958, 1520 .ioctl = snd_pcm_lib_ioctl, 1521 .hw_params = snd_cs46xx_playback_hw_params, 1522 .hw_free = snd_cs46xx_playback_hw_free, 1523 .prepare = snd_cs46xx_playback_prepare, 1524 .trigger = snd_cs46xx_playback_trigger, 1525 .pointer = snd_cs46xx_playback_indirect_pointer, 1526 .ack = snd_cs46xx_playback_transfer, 1527 }; 1528 1529 #endif 1530 1531 static snd_pcm_ops_t snd_cs46xx_playback_ops = { 1532 .open = snd_cs46xx_playback_open, 1533 .close = snd_cs46xx_playback_close, 1534 .ioctl = snd_pcm_lib_ioctl, 1535 .hw_params = snd_cs46xx_playback_hw_params, 1536 .hw_free = snd_cs46xx_playback_hw_free, 1537 .prepare = snd_cs46xx_playback_prepare, 1538 .trigger = snd_cs46xx_playback_trigger, 1539 .pointer = snd_cs46xx_playback_direct_pointer, 1540 }; 1541 1542 static snd_pcm_ops_t snd_cs46xx_playback_indirect_ops = { 1543 .open = snd_cs46xx_playback_open, 1544 .close = snd_cs46xx_playback_close, 1545 .ioctl = snd_pcm_lib_ioctl, 1546 .hw_params = snd_cs46xx_playback_hw_params, 1547 .hw_free = snd_cs46xx_playback_hw_free, 1548 .prepare = snd_cs46xx_playback_prepare, 1549 .trigger = snd_cs46xx_playback_trigger, 1550 .pointer = snd_cs46xx_playback_indirect_pointer, 1551 .ack = snd_cs46xx_playback_transfer, 1552 }; 1553 1554 static snd_pcm_ops_t snd_cs46xx_capture_ops = { 1555 .open = snd_cs46xx_capture_open, 1556 .close = snd_cs46xx_capture_close, 1557 .ioctl = snd_pcm_lib_ioctl, 1558 .hw_params = snd_cs46xx_capture_hw_params, 1559 .hw_free = snd_cs46xx_capture_hw_free, 1560 .prepare = snd_cs46xx_capture_prepare, 1561 .trigger = snd_cs46xx_capture_trigger, 1562 .pointer = snd_cs46xx_capture_direct_pointer, 1563 }; 1564 1565 static snd_pcm_ops_t snd_cs46xx_capture_indirect_ops = { 1566 .open = snd_cs46xx_capture_open, 1567 .close = snd_cs46xx_capture_close, 1568 .ioctl = snd_pcm_lib_ioctl, 1569 .hw_params = snd_cs46xx_capture_hw_params, 1570 .hw_free = snd_cs46xx_capture_hw_free, 1571 .prepare = snd_cs46xx_capture_prepare, 1572 .trigger = snd_cs46xx_capture_trigger, 1573 .pointer = snd_cs46xx_capture_indirect_pointer, 1574 .ack = snd_cs46xx_capture_transfer, 1575 }; 1576 1577 static void snd_cs46xx_pcm_free(snd_pcm_t *pcm) 1578 { 1579 cs46xx_t *chip = pcm->private_data; 1580 chip->pcm = NULL; 1581 snd_pcm_lib_preallocate_free_for_all(pcm); 1582 } 1583 1584 #ifdef CONFIG_SND_CS46XX_NEW_DSP 1585 static void snd_cs46xx_pcm_rear_free(snd_pcm_t *pcm) 1586 { 1587 cs46xx_t *chip = pcm->private_data; 1588 chip->pcm_rear = NULL; 1589 snd_pcm_lib_preallocate_free_for_all(pcm); 1590 } 1591 1592 static void snd_cs46xx_pcm_center_lfe_free(snd_pcm_t *pcm) 1593 { 1594 cs46xx_t *chip = pcm->private_data; 1595 chip->pcm_center_lfe = NULL; 1596 snd_pcm_lib_preallocate_free_for_all(pcm); 1597 } 1598 1599 static void snd_cs46xx_pcm_iec958_free(snd_pcm_t *pcm) 1600 { 1601 cs46xx_t *chip = pcm->private_data; 1602 chip->pcm_iec958 = NULL; 1603 snd_pcm_lib_preallocate_free_for_all(pcm); 1604 } 1605 1606 #define MAX_PLAYBACK_CHANNELS (DSP_MAX_PCM_CHANNELS - 1) 1607 #else 1608 #define MAX_PLAYBACK_CHANNELS 1 1609 #endif 1610 1611 int __devinit snd_cs46xx_pcm(cs46xx_t *chip, int device, snd_pcm_t ** rpcm) 1612 { 1613 snd_pcm_t *pcm; 1614 int err; 1615 1616 if (rpcm) 1617 *rpcm = NULL; 1618 if ((err = snd_pcm_new(chip->card, "CS46xx", device, MAX_PLAYBACK_CHANNELS, 1, &pcm)) < 0) 1619 return err; 1620 1621 pcm->private_data = chip; 1622 pcm->private_free = snd_cs46xx_pcm_free; 1623 1624 snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, &snd_cs46xx_playback_ops); 1625 snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE, &snd_cs46xx_capture_ops); 1626 1627 /* global setup */ 1628 pcm->info_flags = 0; 1629 strcpy(pcm->name, "CS46xx"); 1630 chip->pcm = pcm; 1631 1632 snd_pcm_lib_preallocate_pages_for_all(pcm, SNDRV_DMA_TYPE_DEV, 1633 snd_dma_pci_data(chip->pci), 64*1024, 256*1024); 1634 1635 if (rpcm) 1636 *rpcm = pcm; 1637 1638 return 0; 1639 } 1640 1641 1642 #ifdef CONFIG_SND_CS46XX_NEW_DSP 1643 int __devinit snd_cs46xx_pcm_rear(cs46xx_t *chip, int device, snd_pcm_t ** rpcm) 1644 { 1645 snd_pcm_t *pcm; 1646 int err; 1647 1648 if (rpcm) 1649 *rpcm = NULL; 1650 1651 if ((err = snd_pcm_new(chip->card, "CS46xx - Rear", device, MAX_PLAYBACK_CHANNELS, 0, &pcm)) < 0) 1652 return err; 1653 1654 pcm->private_data = chip; 1655 pcm->private_free = snd_cs46xx_pcm_rear_free; 1656 1657 snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, &snd_cs46xx_playback_rear_ops); 1658 1659 /* global setup */ 1660 pcm->info_flags = 0; 1661 strcpy(pcm->name, "CS46xx - Rear"); 1662 chip->pcm_rear = pcm; 1663 1664 snd_pcm_lib_preallocate_pages_for_all(pcm, SNDRV_DMA_TYPE_DEV, 1665 snd_dma_pci_data(chip->pci), 64*1024, 256*1024); 1666 1667 if (rpcm) 1668 *rpcm = pcm; 1669 1670 return 0; 1671 } 1672 1673 int __devinit snd_cs46xx_pcm_center_lfe(cs46xx_t *chip, int device, snd_pcm_t ** rpcm) 1674 { 1675 snd_pcm_t *pcm; 1676 int err; 1677 1678 if (rpcm) 1679 *rpcm = NULL; 1680 1681 if ((err = snd_pcm_new(chip->card, "CS46xx - Center LFE", device, MAX_PLAYBACK_CHANNELS, 0, &pcm)) < 0) 1682 return err; 1683 1684 pcm->private_data = chip; 1685 pcm->private_free = snd_cs46xx_pcm_center_lfe_free; 1686 1687 snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, &snd_cs46xx_playback_clfe_ops); 1688 1689 /* global setup */ 1690 pcm->info_flags = 0; 1691 strcpy(pcm->name, "CS46xx - Center LFE"); 1692 chip->pcm_center_lfe = pcm; 1693 1694 snd_pcm_lib_preallocate_pages_for_all(pcm, SNDRV_DMA_TYPE_DEV, 1695 snd_dma_pci_data(chip->pci), 64*1024, 256*1024); 1696 1697 if (rpcm) 1698 *rpcm = pcm; 1699 1700 return 0; 1701 } 1702 1703 int __devinit snd_cs46xx_pcm_iec958(cs46xx_t *chip, int device, snd_pcm_t ** rpcm) 1704 { 1705 snd_pcm_t *pcm; 1706 int err; 1707 1708 if (rpcm) 1709 *rpcm = NULL; 1710 1711 if ((err = snd_pcm_new(chip->card, "CS46xx - IEC958", device, 1, 0, &pcm)) < 0) 1712 return err; 1713 1714 pcm->private_data = chip; 1715 pcm->private_free = snd_cs46xx_pcm_iec958_free; 1716 1717 snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, &snd_cs46xx_playback_iec958_ops); 1718 1719 /* global setup */ 1720 pcm->info_flags = 0; 1721 strcpy(pcm->name, "CS46xx - IEC958"); 1722 chip->pcm_rear = pcm; 1723 1724 snd_pcm_lib_preallocate_pages_for_all(pcm, SNDRV_DMA_TYPE_DEV, 1725 snd_dma_pci_data(chip->pci), 64*1024, 256*1024); 1726 1727 if (rpcm) 1728 *rpcm = pcm; 1729 1730 return 0; 1731 } 1732 #endif 1733 1734 /* 1735 * Mixer routines 1736 */ 1737 static void snd_cs46xx_mixer_free_ac97_bus(ac97_bus_t *bus) 1738 { 1739 cs46xx_t *chip = bus->private_data; 1740 1741 chip->ac97_bus = NULL; 1742 } 1743 1744 static void snd_cs46xx_mixer_free_ac97(ac97_t *ac97) 1745 { 1746 cs46xx_t *chip = ac97->private_data; 1747 1748 snd_assert ((ac97 == chip->ac97[CS46XX_PRIMARY_CODEC_INDEX]) || 1749 (ac97 == chip->ac97[CS46XX_SECONDARY_CODEC_INDEX]), 1750 return); 1751 1752 if (ac97 == chip->ac97[CS46XX_PRIMARY_CODEC_INDEX]) { 1753 chip->ac97[CS46XX_PRIMARY_CODEC_INDEX] = NULL; 1754 chip->eapd_switch = NULL; 1755 } 1756 else 1757 chip->ac97[CS46XX_SECONDARY_CODEC_INDEX] = NULL; 1758 } 1759 1760 static int snd_cs46xx_vol_info(snd_kcontrol_t *kcontrol, 1761 snd_ctl_elem_info_t *uinfo) 1762 { 1763 uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER; 1764 uinfo->count = 2; 1765 uinfo->value.integer.min = 0; 1766 uinfo->value.integer.max = 0x7fff; 1767 return 0; 1768 } 1769 1770 static int snd_cs46xx_vol_get(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol) 1771 { 1772 cs46xx_t *chip = snd_kcontrol_chip(kcontrol); 1773 int reg = kcontrol->private_value; 1774 unsigned int val = snd_cs46xx_peek(chip, reg); 1775 ucontrol->value.integer.value[0] = 0xffff - (val >> 16); 1776 ucontrol->value.integer.value[1] = 0xffff - (val & 0xffff); 1777 return 0; 1778 } 1779 1780 static int snd_cs46xx_vol_put(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol) 1781 { 1782 cs46xx_t *chip = snd_kcontrol_chip(kcontrol); 1783 int reg = kcontrol->private_value; 1784 unsigned int val = ((0xffff - ucontrol->value.integer.value[0]) << 16 | 1785 (0xffff - ucontrol->value.integer.value[1])); 1786 unsigned int old = snd_cs46xx_peek(chip, reg); 1787 int change = (old != val); 1788 1789 if (change) { 1790 snd_cs46xx_poke(chip, reg, val); 1791 } 1792 1793 return change; 1794 } 1795 1796 #ifdef CONFIG_SND_CS46XX_NEW_DSP 1797 1798 static int snd_cs46xx_vol_dac_get(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol) 1799 { 1800 cs46xx_t *chip = snd_kcontrol_chip(kcontrol); 1801 1802 ucontrol->value.integer.value[0] = chip->dsp_spos_instance->dac_volume_left; 1803 ucontrol->value.integer.value[1] = chip->dsp_spos_instance->dac_volume_right; 1804 1805 return 0; 1806 } 1807 1808 static int snd_cs46xx_vol_dac_put(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol) 1809 { 1810 cs46xx_t *chip = snd_kcontrol_chip(kcontrol); 1811 int change = 0; 1812 1813 if (chip->dsp_spos_instance->dac_volume_right != ucontrol->value.integer.value[0] || 1814 chip->dsp_spos_instance->dac_volume_left != ucontrol->value.integer.value[1]) { 1815 cs46xx_dsp_set_dac_volume(chip, 1816 ucontrol->value.integer.value[0], 1817 ucontrol->value.integer.value[1]); 1818 change = 1; 1819 } 1820 1821 return change; 1822 } 1823 1824 #if 0 1825 static int snd_cs46xx_vol_iec958_get(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol) 1826 { 1827 cs46xx_t *chip = snd_kcontrol_chip(kcontrol); 1828 1829 ucontrol->value.integer.value[0] = chip->dsp_spos_instance->spdif_input_volume_left; 1830 ucontrol->value.integer.value[1] = chip->dsp_spos_instance->spdif_input_volume_right; 1831 return 0; 1832 } 1833 1834 static int snd_cs46xx_vol_iec958_put(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol) 1835 { 1836 cs46xx_t *chip = snd_kcontrol_chip(kcontrol); 1837 int change = 0; 1838 1839 if (chip->dsp_spos_instance->spdif_input_volume_left != ucontrol->value.integer.value[0] || 1840 chip->dsp_spos_instance->spdif_input_volume_right!= ucontrol->value.integer.value[1]) { 1841 cs46xx_dsp_set_iec958_volume (chip, 1842 ucontrol->value.integer.value[0], 1843 ucontrol->value.integer.value[1]); 1844 change = 1; 1845 } 1846 1847 return change; 1848 } 1849 #endif 1850 1851 static int snd_mixer_boolean_info(snd_kcontrol_t *kcontrol, 1852 snd_ctl_elem_info_t *uinfo) 1853 { 1854 uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN; 1855 uinfo->count = 1; 1856 uinfo->value.integer.min = 0; 1857 uinfo->value.integer.max = 1; 1858 return 0; 1859 } 1860 1861 static int snd_cs46xx_iec958_get(snd_kcontrol_t *kcontrol, 1862 snd_ctl_elem_value_t *ucontrol) 1863 { 1864 cs46xx_t *chip = snd_kcontrol_chip(kcontrol); 1865 int reg = kcontrol->private_value; 1866 1867 if (reg == CS46XX_MIXER_SPDIF_OUTPUT_ELEMENT) 1868 ucontrol->value.integer.value[0] = (chip->dsp_spos_instance->spdif_status_out & DSP_SPDIF_STATUS_OUTPUT_ENABLED); 1869 else 1870 ucontrol->value.integer.value[0] = chip->dsp_spos_instance->spdif_status_in; 1871 1872 return 0; 1873 } 1874 1875 static int snd_cs46xx_iec958_put(snd_kcontrol_t *kcontrol, 1876 snd_ctl_elem_value_t *ucontrol) 1877 { 1878 cs46xx_t *chip = snd_kcontrol_chip(kcontrol); 1879 int change, res; 1880 1881 switch (kcontrol->private_value) { 1882 case CS46XX_MIXER_SPDIF_OUTPUT_ELEMENT: 1883 down (&chip->spos_mutex); 1884 change = (chip->dsp_spos_instance->spdif_status_out & DSP_SPDIF_STATUS_OUTPUT_ENABLED); 1885 if (ucontrol->value.integer.value[0] && !change) 1886 cs46xx_dsp_enable_spdif_out(chip); 1887 else if (change && !ucontrol->value.integer.value[0]) 1888 cs46xx_dsp_disable_spdif_out(chip); 1889 1890 res = (change != (chip->dsp_spos_instance->spdif_status_out & DSP_SPDIF_STATUS_OUTPUT_ENABLED)); 1891 up (&chip->spos_mutex); 1892 break; 1893 case CS46XX_MIXER_SPDIF_INPUT_ELEMENT: 1894 change = chip->dsp_spos_instance->spdif_status_in; 1895 if (ucontrol->value.integer.value[0] && !change) { 1896 cs46xx_dsp_enable_spdif_in(chip); 1897 /* restore volume */ 1898 } 1899 else if (change && !ucontrol->value.integer.value[0]) 1900 cs46xx_dsp_disable_spdif_in(chip); 1901 1902 res = (change != chip->dsp_spos_instance->spdif_status_in); 1903 break; 1904 default: 1905 res = -EINVAL; 1906 snd_assert(0, (void)0); 1907 } 1908 1909 return res; 1910 } 1911 1912 static int snd_cs46xx_adc_capture_get(snd_kcontrol_t *kcontrol, 1913 snd_ctl_elem_value_t *ucontrol) 1914 { 1915 cs46xx_t *chip = snd_kcontrol_chip(kcontrol); 1916 dsp_spos_instance_t * ins = chip->dsp_spos_instance; 1917 1918 if (ins->adc_input != NULL) 1919 ucontrol->value.integer.value[0] = 1; 1920 else 1921 ucontrol->value.integer.value[0] = 0; 1922 1923 return 0; 1924 } 1925 1926 static int snd_cs46xx_adc_capture_put(snd_kcontrol_t *kcontrol, 1927 snd_ctl_elem_value_t *ucontrol) 1928 { 1929 cs46xx_t *chip = snd_kcontrol_chip(kcontrol); 1930 dsp_spos_instance_t * ins = chip->dsp_spos_instance; 1931 int change = 0; 1932 1933 if (ucontrol->value.integer.value[0] && !ins->adc_input) { 1934 cs46xx_dsp_enable_adc_capture(chip); 1935 change = 1; 1936 } else if (!ucontrol->value.integer.value[0] && ins->adc_input) { 1937 cs46xx_dsp_disable_adc_capture(chip); 1938 change = 1; 1939 } 1940 return change; 1941 } 1942 1943 static int snd_cs46xx_pcm_capture_get(snd_kcontrol_t *kcontrol, 1944 snd_ctl_elem_value_t *ucontrol) 1945 { 1946 cs46xx_t *chip = snd_kcontrol_chip(kcontrol); 1947 dsp_spos_instance_t * ins = chip->dsp_spos_instance; 1948 1949 if (ins->pcm_input != NULL) 1950 ucontrol->value.integer.value[0] = 1; 1951 else 1952 ucontrol->value.integer.value[0] = 0; 1953 1954 return 0; 1955 } 1956 1957 1958 static int snd_cs46xx_pcm_capture_put(snd_kcontrol_t *kcontrol, 1959 snd_ctl_elem_value_t *ucontrol) 1960 { 1961 cs46xx_t *chip = snd_kcontrol_chip(kcontrol); 1962 dsp_spos_instance_t * ins = chip->dsp_spos_instance; 1963 int change = 0; 1964 1965 if (ucontrol->value.integer.value[0] && !ins->pcm_input) { 1966 cs46xx_dsp_enable_pcm_capture(chip); 1967 change = 1; 1968 } else if (!ucontrol->value.integer.value[0] && ins->pcm_input) { 1969 cs46xx_dsp_disable_pcm_capture(chip); 1970 change = 1; 1971 } 1972 1973 return change; 1974 } 1975 1976 static int snd_herc_spdif_select_get(snd_kcontrol_t *kcontrol, 1977 snd_ctl_elem_value_t *ucontrol) 1978 { 1979 cs46xx_t *chip = snd_kcontrol_chip(kcontrol); 1980 1981 int val1 = snd_cs46xx_peekBA0(chip, BA0_EGPIODR); 1982 1983 if (val1 & EGPIODR_GPOE0) 1984 ucontrol->value.integer.value[0] = 1; 1985 else 1986 ucontrol->value.integer.value[0] = 0; 1987 1988 return 0; 1989 } 1990 1991 /* 1992 * Game Theatre XP card - EGPIO[0] is used to select SPDIF input optical or coaxial. 1993 */ 1994 static int snd_herc_spdif_select_put(snd_kcontrol_t *kcontrol, 1995 snd_ctl_elem_value_t *ucontrol) 1996 { 1997 cs46xx_t *chip = snd_kcontrol_chip(kcontrol); 1998 int val1 = snd_cs46xx_peekBA0(chip, BA0_EGPIODR); 1999 int val2 = snd_cs46xx_peekBA0(chip, BA0_EGPIOPTR); 2000 2001 if (ucontrol->value.integer.value[0]) { 2002 /* optical is default */ 2003 snd_cs46xx_pokeBA0(chip, BA0_EGPIODR, 2004 EGPIODR_GPOE0 | val1); /* enable EGPIO0 output */ 2005 snd_cs46xx_pokeBA0(chip, BA0_EGPIOPTR, 2006 EGPIOPTR_GPPT0 | val2); /* open-drain on output */ 2007 } else { 2008 /* coaxial */ 2009 snd_cs46xx_pokeBA0(chip, BA0_EGPIODR, val1 & ~EGPIODR_GPOE0); /* disable */ 2010 snd_cs46xx_pokeBA0(chip, BA0_EGPIOPTR, val2 & ~EGPIOPTR_GPPT0); /* disable */ 2011 } 2012 2013 /* checking diff from the EGPIO direction register 2014 should be enough */ 2015 return (val1 != (int)snd_cs46xx_peekBA0(chip, BA0_EGPIODR)); 2016 } 2017 2018 2019 static int snd_cs46xx_spdif_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t * uinfo) 2020 { 2021 uinfo->type = SNDRV_CTL_ELEM_TYPE_IEC958; 2022 uinfo->count = 1; 2023 return 0; 2024 } 2025 2026 static int snd_cs46xx_spdif_default_get(snd_kcontrol_t * kcontrol, 2027 snd_ctl_elem_value_t * ucontrol) 2028 { 2029 cs46xx_t *chip = snd_kcontrol_chip(kcontrol); 2030 dsp_spos_instance_t * ins = chip->dsp_spos_instance; 2031 2032 down (&chip->spos_mutex); 2033 ucontrol->value.iec958.status[0] = _wrap_all_bits((ins->spdif_csuv_default >> 24) & 0xff); 2034 ucontrol->value.iec958.status[1] = _wrap_all_bits((ins->spdif_csuv_default >> 16) & 0xff); 2035 ucontrol->value.iec958.status[2] = 0; 2036 ucontrol->value.iec958.status[3] = _wrap_all_bits((ins->spdif_csuv_default) & 0xff); 2037 up (&chip->spos_mutex); 2038 2039 return 0; 2040 } 2041 2042 static int snd_cs46xx_spdif_default_put(snd_kcontrol_t * kcontrol, 2043 snd_ctl_elem_value_t * ucontrol) 2044 { 2045 cs46xx_t * chip = snd_kcontrol_chip(kcontrol); 2046 dsp_spos_instance_t * ins = chip->dsp_spos_instance; 2047 unsigned int val; 2048 int change; 2049 2050 down (&chip->spos_mutex); 2051 val = ((unsigned int)_wrap_all_bits(ucontrol->value.iec958.status[0]) << 24) | 2052 ((unsigned int)_wrap_all_bits(ucontrol->value.iec958.status[2]) << 16) | 2053 ((unsigned int)_wrap_all_bits(ucontrol->value.iec958.status[3])) | 2054 /* left and right validity bit */ 2055 (1 << 13) | (1 << 12); 2056 2057 2058 change = (unsigned int)ins->spdif_csuv_default != val; 2059 ins->spdif_csuv_default = val; 2060 2061 if ( !(ins->spdif_status_out & DSP_SPDIF_STATUS_PLAYBACK_OPEN) ) 2062 cs46xx_poke_via_dsp (chip,SP_SPDOUT_CSUV,val); 2063 2064 up (&chip->spos_mutex); 2065 2066 return change; 2067 } 2068 2069 static int snd_cs46xx_spdif_mask_get(snd_kcontrol_t * kcontrol, 2070 snd_ctl_elem_value_t * ucontrol) 2071 { 2072 ucontrol->value.iec958.status[0] = 0xff; 2073 ucontrol->value.iec958.status[1] = 0xff; 2074 ucontrol->value.iec958.status[2] = 0x00; 2075 ucontrol->value.iec958.status[3] = 0xff; 2076 return 0; 2077 } 2078 2079 static int snd_cs46xx_spdif_stream_get(snd_kcontrol_t * kcontrol, 2080 snd_ctl_elem_value_t * ucontrol) 2081 { 2082 cs46xx_t *chip = snd_kcontrol_chip(kcontrol); 2083 dsp_spos_instance_t * ins = chip->dsp_spos_instance; 2084 2085 down (&chip->spos_mutex); 2086 ucontrol->value.iec958.status[0] = _wrap_all_bits((ins->spdif_csuv_stream >> 24) & 0xff); 2087 ucontrol->value.iec958.status[1] = _wrap_all_bits((ins->spdif_csuv_stream >> 16) & 0xff); 2088 ucontrol->value.iec958.status[2] = 0; 2089 ucontrol->value.iec958.status[3] = _wrap_all_bits((ins->spdif_csuv_stream) & 0xff); 2090 up (&chip->spos_mutex); 2091 2092 return 0; 2093 } 2094 2095 static int snd_cs46xx_spdif_stream_put(snd_kcontrol_t * kcontrol, 2096 snd_ctl_elem_value_t * ucontrol) 2097 { 2098 cs46xx_t * chip = snd_kcontrol_chip(kcontrol); 2099 dsp_spos_instance_t * ins = chip->dsp_spos_instance; 2100 unsigned int val; 2101 int change; 2102 2103 down (&chip->spos_mutex); 2104 val = ((unsigned int)_wrap_all_bits(ucontrol->value.iec958.status[0]) << 24) | 2105 ((unsigned int)_wrap_all_bits(ucontrol->value.iec958.status[1]) << 16) | 2106 ((unsigned int)_wrap_all_bits(ucontrol->value.iec958.status[3])) | 2107 /* left and right validity bit */ 2108 (1 << 13) | (1 << 12); 2109 2110 2111 change = ins->spdif_csuv_stream != val; 2112 ins->spdif_csuv_stream = val; 2113 2114 if ( ins->spdif_status_out & DSP_SPDIF_STATUS_PLAYBACK_OPEN ) 2115 cs46xx_poke_via_dsp (chip,SP_SPDOUT_CSUV,val); 2116 2117 up (&chip->spos_mutex); 2118 2119 return change; 2120 } 2121 2122 #endif /* CONFIG_SND_CS46XX_NEW_DSP */ 2123 2124 2125 #ifdef CONFIG_SND_CS46XX_DEBUG_GPIO 2126 static int snd_cs46xx_egpio_select_info(snd_kcontrol_t *kcontrol, 2127 snd_ctl_elem_info_t *uinfo) 2128 { 2129 uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER; 2130 uinfo->count = 1; 2131 uinfo->value.integer.min = 0; 2132 uinfo->value.integer.max = 8; 2133 return 0; 2134 } 2135 2136 static int snd_cs46xx_egpio_select_get(snd_kcontrol_t *kcontrol, 2137 snd_ctl_elem_value_t *ucontrol) 2138 { 2139 cs46xx_t *chip = snd_kcontrol_chip(kcontrol); 2140 ucontrol->value.integer.value[0] = chip->current_gpio; 2141 2142 return 0; 2143 } 2144 2145 static int snd_cs46xx_egpio_select_put(snd_kcontrol_t *kcontrol, 2146 snd_ctl_elem_value_t *ucontrol) 2147 { 2148 cs46xx_t *chip = snd_kcontrol_chip(kcontrol); 2149 int change = (chip->current_gpio != ucontrol->value.integer.value[0]); 2150 chip->current_gpio = ucontrol->value.integer.value[0]; 2151 2152 return change; 2153 } 2154 2155 2156 static int snd_cs46xx_egpio_get(snd_kcontrol_t *kcontrol, 2157 snd_ctl_elem_value_t *ucontrol) 2158 { 2159 cs46xx_t *chip = snd_kcontrol_chip(kcontrol); 2160 int reg = kcontrol->private_value; 2161 2162 snd_printdd ("put: reg = %04x, gpio %02x\n",reg,chip->current_gpio); 2163 ucontrol->value.integer.value[0] = 2164 (snd_cs46xx_peekBA0(chip, reg) & (1 << chip->current_gpio)) ? 1 : 0; 2165 2166 return 0; 2167 } 2168 2169 static int snd_cs46xx_egpio_put(snd_kcontrol_t *kcontrol, 2170 snd_ctl_elem_value_t *ucontrol) 2171 { 2172 cs46xx_t *chip = snd_kcontrol_chip(kcontrol); 2173 int reg = kcontrol->private_value; 2174 int val = snd_cs46xx_peekBA0(chip, reg); 2175 int oldval = val; 2176 snd_printdd ("put: reg = %04x, gpio %02x\n",reg,chip->current_gpio); 2177 2178 if (ucontrol->value.integer.value[0]) 2179 val |= (1 << chip->current_gpio); 2180 else 2181 val &= ~(1 << chip->current_gpio); 2182 2183 snd_cs46xx_pokeBA0(chip, reg,val); 2184 snd_printdd ("put: val %08x oldval %08x\n",val,oldval); 2185 2186 return (oldval != val); 2187 } 2188 #endif /* CONFIG_SND_CS46XX_DEBUG_GPIO */ 2189 2190 static snd_kcontrol_new_t snd_cs46xx_controls[] __devinitdata = { 2191 { 2192 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 2193 .name = "DAC Volume", 2194 .info = snd_cs46xx_vol_info, 2195 #ifndef CONFIG_SND_CS46XX_NEW_DSP 2196 .get = snd_cs46xx_vol_get, 2197 .put = snd_cs46xx_vol_put, 2198 .private_value = BA1_PVOL, 2199 #else 2200 .get = snd_cs46xx_vol_dac_get, 2201 .put = snd_cs46xx_vol_dac_put, 2202 #endif 2203 }, 2204 2205 { 2206 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 2207 .name = "ADC Volume", 2208 .info = snd_cs46xx_vol_info, 2209 .get = snd_cs46xx_vol_get, 2210 .put = snd_cs46xx_vol_put, 2211 #ifndef CONFIG_SND_CS46XX_NEW_DSP 2212 .private_value = BA1_CVOL, 2213 #else 2214 .private_value = (VARIDECIMATE_SCB_ADDR + 0xE) << 2, 2215 #endif 2216 }, 2217 #ifdef CONFIG_SND_CS46XX_NEW_DSP 2218 { 2219 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 2220 .name = "ADC Capture Switch", 2221 .info = snd_mixer_boolean_info, 2222 .get = snd_cs46xx_adc_capture_get, 2223 .put = snd_cs46xx_adc_capture_put 2224 }, 2225 { 2226 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 2227 .name = "DAC Capture Switch", 2228 .info = snd_mixer_boolean_info, 2229 .get = snd_cs46xx_pcm_capture_get, 2230 .put = snd_cs46xx_pcm_capture_put 2231 }, 2232 { 2233 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 2234 .name = SNDRV_CTL_NAME_IEC958("Output ",NONE,SWITCH), 2235 .info = snd_mixer_boolean_info, 2236 .get = snd_cs46xx_iec958_get, 2237 .put = snd_cs46xx_iec958_put, 2238 .private_value = CS46XX_MIXER_SPDIF_OUTPUT_ELEMENT, 2239 }, 2240 { 2241 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 2242 .name = SNDRV_CTL_NAME_IEC958("Input ",NONE,SWITCH), 2243 .info = snd_mixer_boolean_info, 2244 .get = snd_cs46xx_iec958_get, 2245 .put = snd_cs46xx_iec958_put, 2246 .private_value = CS46XX_MIXER_SPDIF_INPUT_ELEMENT, 2247 }, 2248 #if 0 2249 /* Input IEC958 volume does not work for the moment. (Benny) */ 2250 { 2251 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 2252 .name = SNDRV_CTL_NAME_IEC958("Input ",NONE,VOLUME), 2253 .info = snd_cs46xx_vol_info, 2254 .get = snd_cs46xx_vol_iec958_get, 2255 .put = snd_cs46xx_vol_iec958_put, 2256 .private_value = (ASYNCRX_SCB_ADDR + 0xE) << 2, 2257 }, 2258 #endif 2259 { 2260 .iface = SNDRV_CTL_ELEM_IFACE_PCM, 2261 .name = SNDRV_CTL_NAME_IEC958("",PLAYBACK,DEFAULT), 2262 .info = snd_cs46xx_spdif_info, 2263 .get = snd_cs46xx_spdif_default_get, 2264 .put = snd_cs46xx_spdif_default_put, 2265 }, 2266 { 2267 .iface = SNDRV_CTL_ELEM_IFACE_PCM, 2268 .name = SNDRV_CTL_NAME_IEC958("",PLAYBACK,MASK), 2269 .info = snd_cs46xx_spdif_info, 2270 .get = snd_cs46xx_spdif_mask_get, 2271 .access = SNDRV_CTL_ELEM_ACCESS_READ 2272 }, 2273 { 2274 .iface = SNDRV_CTL_ELEM_IFACE_PCM, 2275 .name = SNDRV_CTL_NAME_IEC958("",PLAYBACK,PCM_STREAM), 2276 .info = snd_cs46xx_spdif_info, 2277 .get = snd_cs46xx_spdif_stream_get, 2278 .put = snd_cs46xx_spdif_stream_put 2279 }, 2280 2281 #endif 2282 #ifdef CONFIG_SND_CS46XX_DEBUG_GPIO 2283 { 2284 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 2285 .name = "EGPIO select", 2286 .info = snd_cs46xx_egpio_select_info, 2287 .get = snd_cs46xx_egpio_select_get, 2288 .put = snd_cs46xx_egpio_select_put, 2289 .private_value = 0, 2290 }, 2291 { 2292 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 2293 .name = "EGPIO Input/Output", 2294 .info = snd_mixer_boolean_info, 2295 .get = snd_cs46xx_egpio_get, 2296 .put = snd_cs46xx_egpio_put, 2297 .private_value = BA0_EGPIODR, 2298 }, 2299 { 2300 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 2301 .name = "EGPIO CMOS/Open drain", 2302 .info = snd_mixer_boolean_info, 2303 .get = snd_cs46xx_egpio_get, 2304 .put = snd_cs46xx_egpio_put, 2305 .private_value = BA0_EGPIOPTR, 2306 }, 2307 { 2308 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 2309 .name = "EGPIO On/Off", 2310 .info = snd_mixer_boolean_info, 2311 .get = snd_cs46xx_egpio_get, 2312 .put = snd_cs46xx_egpio_put, 2313 .private_value = BA0_EGPIOSR, 2314 }, 2315 #endif 2316 }; 2317 2318 #ifdef CONFIG_SND_CS46XX_NEW_DSP 2319 /* set primary cs4294 codec into Extended Audio Mode */ 2320 static int snd_cs46xx_front_dup_get(snd_kcontrol_t *kcontrol, 2321 snd_ctl_elem_value_t *ucontrol) 2322 { 2323 cs46xx_t *chip = snd_kcontrol_chip(kcontrol); 2324 unsigned short val; 2325 val = snd_ac97_read(chip->ac97[CS46XX_PRIMARY_CODEC_INDEX], AC97_CSR_ACMODE); 2326 ucontrol->value.integer.value[0] = (val & 0x200) ? 0 : 1; 2327 return 0; 2328 } 2329 2330 static int snd_cs46xx_front_dup_put(snd_kcontrol_t *kcontrol, 2331 snd_ctl_elem_value_t *ucontrol) 2332 { 2333 cs46xx_t *chip = snd_kcontrol_chip(kcontrol); 2334 return snd_ac97_update_bits(chip->ac97[CS46XX_PRIMARY_CODEC_INDEX], 2335 AC97_CSR_ACMODE, 0x200, 2336 ucontrol->value.integer.value[0] ? 0 : 0x200); 2337 } 2338 2339 static snd_kcontrol_new_t snd_cs46xx_front_dup_ctl = { 2340 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 2341 .name = "Duplicate Front", 2342 .info = snd_mixer_boolean_info, 2343 .get = snd_cs46xx_front_dup_get, 2344 .put = snd_cs46xx_front_dup_put, 2345 }; 2346 #endif 2347 2348 #ifdef CONFIG_SND_CS46XX_NEW_DSP 2349 /* Only available on the Hercules Game Theater XP soundcard */ 2350 static snd_kcontrol_new_t snd_hercules_controls[] __devinitdata = { 2351 { 2352 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 2353 .name = "Optical/Coaxial SPDIF Input Switch", 2354 .info = snd_mixer_boolean_info, 2355 .get = snd_herc_spdif_select_get, 2356 .put = snd_herc_spdif_select_put, 2357 }, 2358 }; 2359 2360 2361 static void snd_cs46xx_codec_reset (ac97_t * ac97) 2362 { 2363 unsigned long end_time; 2364 int err; 2365 2366 /* reset to defaults */ 2367 snd_ac97_write(ac97, AC97_RESET, 0); 2368 2369 /* set the desired CODEC mode */ 2370 if (ac97->num == CS46XX_PRIMARY_CODEC_INDEX) { 2371 snd_printdd("cs46xx: CODOEC1 mode %04x\n",0x0); 2372 snd_cs46xx_ac97_write(ac97,AC97_CSR_ACMODE,0x0); 2373 } else if (ac97->num == CS46XX_SECONDARY_CODEC_INDEX) { 2374 snd_printdd("cs46xx: CODOEC2 mode %04x\n",0x3); 2375 snd_cs46xx_ac97_write(ac97,AC97_CSR_ACMODE,0x3); 2376 } else { 2377 snd_assert(0); /* should never happen ... */ 2378 } 2379 2380 udelay(50); 2381 2382 /* it's necessary to wait awhile until registers are accessible after RESET */ 2383 /* because the PCM or MASTER volume registers can be modified, */ 2384 /* the REC_GAIN register is used for tests */ 2385 end_time = jiffies + HZ; 2386 do { 2387 unsigned short ext_mid; 2388 2389 /* use preliminary reads to settle the communication */ 2390 snd_ac97_read(ac97, AC97_RESET); 2391 snd_ac97_read(ac97, AC97_VENDOR_ID1); 2392 snd_ac97_read(ac97, AC97_VENDOR_ID2); 2393 /* modem? */ 2394 ext_mid = snd_ac97_read(ac97, AC97_EXTENDED_MID); 2395 if (ext_mid != 0xffff && (ext_mid & 1) != 0) 2396 return; 2397 2398 /* test if we can write to the record gain volume register */ 2399 snd_ac97_write_cache(ac97, AC97_REC_GAIN, 0x8a05); 2400 if ((err = snd_ac97_read(ac97, AC97_REC_GAIN)) == 0x8a05) 2401 return; 2402 2403 msleep(10); 2404 } while (time_after_eq(end_time, jiffies)); 2405 2406 snd_printk("CS46xx secondary codec dont respond!\n"); 2407 } 2408 #endif 2409 2410 static int __devinit cs46xx_detect_codec(cs46xx_t *chip, int codec) 2411 { 2412 int idx, err; 2413 ac97_template_t ac97; 2414 2415 memset(&ac97, 0, sizeof(ac97)); 2416 ac97.private_data = chip; 2417 ac97.private_free = snd_cs46xx_mixer_free_ac97; 2418 ac97.num = codec; 2419 if (chip->amplifier_ctrl == amp_voyetra) 2420 ac97.scaps = AC97_SCAP_INV_EAPD; 2421 2422 if (codec == CS46XX_SECONDARY_CODEC_INDEX) { 2423 snd_cs46xx_codec_write(chip, AC97_RESET, 0, codec); 2424 udelay(10); 2425 if (snd_cs46xx_codec_read(chip, AC97_RESET, codec) & 0x8000) { 2426 snd_printdd("snd_cs46xx: seconadry codec not present\n"); 2427 return -ENXIO; 2428 } 2429 } 2430 2431 snd_cs46xx_codec_write(chip, AC97_MASTER, 0x8000, codec); 2432 for (idx = 0; idx < 100; ++idx) { 2433 if (snd_cs46xx_codec_read(chip, AC97_MASTER, codec) == 0x8000) { 2434 err = snd_ac97_mixer(chip->ac97_bus, &ac97, &chip->ac97[codec]); 2435 return err; 2436 } 2437 msleep(10); 2438 } 2439 snd_printdd("snd_cs46xx: codec %d detection timeout\n", codec); 2440 return -ENXIO; 2441 } 2442 2443 int __devinit snd_cs46xx_mixer(cs46xx_t *chip, int spdif_device) 2444 { 2445 snd_card_t *card = chip->card; 2446 snd_ctl_elem_id_t id; 2447 int err; 2448 unsigned int idx; 2449 static ac97_bus_ops_t ops = { 2450 #ifdef CONFIG_SND_CS46XX_NEW_DSP 2451 .reset = snd_cs46xx_codec_reset, 2452 #endif 2453 .write = snd_cs46xx_ac97_write, 2454 .read = snd_cs46xx_ac97_read, 2455 }; 2456 2457 /* detect primary codec */ 2458 chip->nr_ac97_codecs = 0; 2459 snd_printdd("snd_cs46xx: detecting primary codec\n"); 2460 if ((err = snd_ac97_bus(card, 0, &ops, chip, &chip->ac97_bus)) < 0) 2461 return err; 2462 chip->ac97_bus->private_free = snd_cs46xx_mixer_free_ac97_bus; 2463 2464 if (cs46xx_detect_codec(chip, CS46XX_PRIMARY_CODEC_INDEX) < 0) 2465 return -ENXIO; 2466 chip->nr_ac97_codecs = 1; 2467 2468 #ifdef CONFIG_SND_CS46XX_NEW_DSP 2469 snd_printdd("snd_cs46xx: detecting seconadry codec\n"); 2470 /* try detect a secondary codec */ 2471 if (! cs46xx_detect_codec(chip, CS46XX_SECONDARY_CODEC_INDEX)) 2472 chip->nr_ac97_codecs = 2; 2473 #endif /* CONFIG_SND_CS46XX_NEW_DSP */ 2474 2475 /* add cs4630 mixer controls */ 2476 for (idx = 0; idx < ARRAY_SIZE(snd_cs46xx_controls); idx++) { 2477 snd_kcontrol_t *kctl; 2478 kctl = snd_ctl_new1(&snd_cs46xx_controls[idx], chip); 2479 if (kctl && kctl->id.iface == SNDRV_CTL_ELEM_IFACE_PCM) 2480 kctl->id.device = spdif_device; 2481 if ((err = snd_ctl_add(card, kctl)) < 0) 2482 return err; 2483 } 2484 2485 /* get EAPD mixer switch (for voyetra hack) */ 2486 memset(&id, 0, sizeof(id)); 2487 id.iface = SNDRV_CTL_ELEM_IFACE_MIXER; 2488 strcpy(id.name, "External Amplifier"); 2489 chip->eapd_switch = snd_ctl_find_id(chip->card, &id); 2490 2491 #ifdef CONFIG_SND_CS46XX_NEW_DSP 2492 if (chip->nr_ac97_codecs == 1) { 2493 unsigned int id2 = chip->ac97[CS46XX_PRIMARY_CODEC_INDEX]->id & 0xffff; 2494 if (id2 == 0x592b || id2 == 0x592d) { 2495 err = snd_ctl_add(card, snd_ctl_new1(&snd_cs46xx_front_dup_ctl, chip)); 2496 if (err < 0) 2497 return err; 2498 snd_ac97_write_cache(chip->ac97[CS46XX_PRIMARY_CODEC_INDEX], 2499 AC97_CSR_ACMODE, 0x200); 2500 } 2501 } 2502 /* do soundcard specific mixer setup */ 2503 if (chip->mixer_init) { 2504 snd_printdd ("calling chip->mixer_init(chip);\n"); 2505 chip->mixer_init(chip); 2506 } 2507 #endif 2508 2509 /* turn on amplifier */ 2510 chip->amplifier_ctrl(chip, 1); 2511 2512 return 0; 2513 } 2514 2515 /* 2516 * RawMIDI interface 2517 */ 2518 2519 static void snd_cs46xx_midi_reset(cs46xx_t *chip) 2520 { 2521 snd_cs46xx_pokeBA0(chip, BA0_MIDCR, MIDCR_MRST); 2522 udelay(100); 2523 snd_cs46xx_pokeBA0(chip, BA0_MIDCR, chip->midcr); 2524 } 2525 2526 static int snd_cs46xx_midi_input_open(snd_rawmidi_substream_t * substream) 2527 { 2528 cs46xx_t *chip = substream->rmidi->private_data; 2529 2530 chip->active_ctrl(chip, 1); 2531 spin_lock_irq(&chip->reg_lock); 2532 chip->uartm |= CS46XX_MODE_INPUT; 2533 chip->midcr |= MIDCR_RXE; 2534 chip->midi_input = substream; 2535 if (!(chip->uartm & CS46XX_MODE_OUTPUT)) { 2536 snd_cs46xx_midi_reset(chip); 2537 } else { 2538 snd_cs46xx_pokeBA0(chip, BA0_MIDCR, chip->midcr); 2539 } 2540 spin_unlock_irq(&chip->reg_lock); 2541 return 0; 2542 } 2543 2544 static int snd_cs46xx_midi_input_close(snd_rawmidi_substream_t * substream) 2545 { 2546 cs46xx_t *chip = substream->rmidi->private_data; 2547 2548 spin_lock_irq(&chip->reg_lock); 2549 chip->midcr &= ~(MIDCR_RXE | MIDCR_RIE); 2550 chip->midi_input = NULL; 2551 if (!(chip->uartm & CS46XX_MODE_OUTPUT)) { 2552 snd_cs46xx_midi_reset(chip); 2553 } else { 2554 snd_cs46xx_pokeBA0(chip, BA0_MIDCR, chip->midcr); 2555 } 2556 chip->uartm &= ~CS46XX_MODE_INPUT; 2557 spin_unlock_irq(&chip->reg_lock); 2558 chip->active_ctrl(chip, -1); 2559 return 0; 2560 } 2561 2562 static int snd_cs46xx_midi_output_open(snd_rawmidi_substream_t * substream) 2563 { 2564 cs46xx_t *chip = substream->rmidi->private_data; 2565 2566 chip->active_ctrl(chip, 1); 2567 2568 spin_lock_irq(&chip->reg_lock); 2569 chip->uartm |= CS46XX_MODE_OUTPUT; 2570 chip->midcr |= MIDCR_TXE; 2571 chip->midi_output = substream; 2572 if (!(chip->uartm & CS46XX_MODE_INPUT)) { 2573 snd_cs46xx_midi_reset(chip); 2574 } else { 2575 snd_cs46xx_pokeBA0(chip, BA0_MIDCR, chip->midcr); 2576 } 2577 spin_unlock_irq(&chip->reg_lock); 2578 return 0; 2579 } 2580 2581 static int snd_cs46xx_midi_output_close(snd_rawmidi_substream_t * substream) 2582 { 2583 cs46xx_t *chip = substream->rmidi->private_data; 2584 2585 spin_lock_irq(&chip->reg_lock); 2586 chip->midcr &= ~(MIDCR_TXE | MIDCR_TIE); 2587 chip->midi_output = NULL; 2588 if (!(chip->uartm & CS46XX_MODE_INPUT)) { 2589 snd_cs46xx_midi_reset(chip); 2590 } else { 2591 snd_cs46xx_pokeBA0(chip, BA0_MIDCR, chip->midcr); 2592 } 2593 chip->uartm &= ~CS46XX_MODE_OUTPUT; 2594 spin_unlock_irq(&chip->reg_lock); 2595 chip->active_ctrl(chip, -1); 2596 return 0; 2597 } 2598 2599 static void snd_cs46xx_midi_input_trigger(snd_rawmidi_substream_t * substream, int up) 2600 { 2601 unsigned long flags; 2602 cs46xx_t *chip = substream->rmidi->private_data; 2603 2604 spin_lock_irqsave(&chip->reg_lock, flags); 2605 if (up) { 2606 if ((chip->midcr & MIDCR_RIE) == 0) { 2607 chip->midcr |= MIDCR_RIE; 2608 snd_cs46xx_pokeBA0(chip, BA0_MIDCR, chip->midcr); 2609 } 2610 } else { 2611 if (chip->midcr & MIDCR_RIE) { 2612 chip->midcr &= ~MIDCR_RIE; 2613 snd_cs46xx_pokeBA0(chip, BA0_MIDCR, chip->midcr); 2614 } 2615 } 2616 spin_unlock_irqrestore(&chip->reg_lock, flags); 2617 } 2618 2619 static void snd_cs46xx_midi_output_trigger(snd_rawmidi_substream_t * substream, int up) 2620 { 2621 unsigned long flags; 2622 cs46xx_t *chip = substream->rmidi->private_data; 2623 unsigned char byte; 2624 2625 spin_lock_irqsave(&chip->reg_lock, flags); 2626 if (up) { 2627 if ((chip->midcr & MIDCR_TIE) == 0) { 2628 chip->midcr |= MIDCR_TIE; 2629 /* fill UART FIFO buffer at first, and turn Tx interrupts only if necessary */ 2630 while ((chip->midcr & MIDCR_TIE) && 2631 (snd_cs46xx_peekBA0(chip, BA0_MIDSR) & MIDSR_TBF) == 0) { 2632 if (snd_rawmidi_transmit(substream, &byte, 1) != 1) { 2633 chip->midcr &= ~MIDCR_TIE; 2634 } else { 2635 snd_cs46xx_pokeBA0(chip, BA0_MIDWP, byte); 2636 } 2637 } 2638 snd_cs46xx_pokeBA0(chip, BA0_MIDCR, chip->midcr); 2639 } 2640 } else { 2641 if (chip->midcr & MIDCR_TIE) { 2642 chip->midcr &= ~MIDCR_TIE; 2643 snd_cs46xx_pokeBA0(chip, BA0_MIDCR, chip->midcr); 2644 } 2645 } 2646 spin_unlock_irqrestore(&chip->reg_lock, flags); 2647 } 2648 2649 static snd_rawmidi_ops_t snd_cs46xx_midi_output = 2650 { 2651 .open = snd_cs46xx_midi_output_open, 2652 .close = snd_cs46xx_midi_output_close, 2653 .trigger = snd_cs46xx_midi_output_trigger, 2654 }; 2655 2656 static snd_rawmidi_ops_t snd_cs46xx_midi_input = 2657 { 2658 .open = snd_cs46xx_midi_input_open, 2659 .close = snd_cs46xx_midi_input_close, 2660 .trigger = snd_cs46xx_midi_input_trigger, 2661 }; 2662 2663 int __devinit snd_cs46xx_midi(cs46xx_t *chip, int device, snd_rawmidi_t **rrawmidi) 2664 { 2665 snd_rawmidi_t *rmidi; 2666 int err; 2667 2668 if (rrawmidi) 2669 *rrawmidi = NULL; 2670 if ((err = snd_rawmidi_new(chip->card, "CS46XX", device, 1, 1, &rmidi)) < 0) 2671 return err; 2672 strcpy(rmidi->name, "CS46XX"); 2673 snd_rawmidi_set_ops(rmidi, SNDRV_RAWMIDI_STREAM_OUTPUT, &snd_cs46xx_midi_output); 2674 snd_rawmidi_set_ops(rmidi, SNDRV_RAWMIDI_STREAM_INPUT, &snd_cs46xx_midi_input); 2675 rmidi->info_flags |= SNDRV_RAWMIDI_INFO_OUTPUT | SNDRV_RAWMIDI_INFO_INPUT | SNDRV_RAWMIDI_INFO_DUPLEX; 2676 rmidi->private_data = chip; 2677 chip->rmidi = rmidi; 2678 if (rrawmidi) 2679 *rrawmidi = NULL; 2680 return 0; 2681 } 2682 2683 2684 /* 2685 * gameport interface 2686 */ 2687 2688 #if defined(CONFIG_GAMEPORT) || (defined(MODULE) && defined(CONFIG_GAMEPORT_MODULE)) 2689 2690 static void snd_cs46xx_gameport_trigger(struct gameport *gameport) 2691 { 2692 cs46xx_t *chip = gameport_get_port_data(gameport); 2693 2694 snd_assert(chip, return); 2695 snd_cs46xx_pokeBA0(chip, BA0_JSPT, 0xFF); //outb(gameport->io, 0xFF); 2696 } 2697 2698 static unsigned char snd_cs46xx_gameport_read(struct gameport *gameport) 2699 { 2700 cs46xx_t *chip = gameport_get_port_data(gameport); 2701 2702 snd_assert(chip, return 0); 2703 return snd_cs46xx_peekBA0(chip, BA0_JSPT); //inb(gameport->io); 2704 } 2705 2706 static int snd_cs46xx_gameport_cooked_read(struct gameport *gameport, int *axes, int *buttons) 2707 { 2708 cs46xx_t *chip = gameport_get_port_data(gameport); 2709 unsigned js1, js2, jst; 2710 2711 snd_assert(chip, return 0); 2712 2713 js1 = snd_cs46xx_peekBA0(chip, BA0_JSC1); 2714 js2 = snd_cs46xx_peekBA0(chip, BA0_JSC2); 2715 jst = snd_cs46xx_peekBA0(chip, BA0_JSPT); 2716 2717 *buttons = (~jst >> 4) & 0x0F; 2718 2719 axes[0] = ((js1 & JSC1_Y1V_MASK) >> JSC1_Y1V_SHIFT) & 0xFFFF; 2720 axes[1] = ((js1 & JSC1_X1V_MASK) >> JSC1_X1V_SHIFT) & 0xFFFF; 2721 axes[2] = ((js2 & JSC2_Y2V_MASK) >> JSC2_Y2V_SHIFT) & 0xFFFF; 2722 axes[3] = ((js2 & JSC2_X2V_MASK) >> JSC2_X2V_SHIFT) & 0xFFFF; 2723 2724 for(jst=0;jst<4;++jst) 2725 if(axes[jst]==0xFFFF) axes[jst] = -1; 2726 return 0; 2727 } 2728 2729 static int snd_cs46xx_gameport_open(struct gameport *gameport, int mode) 2730 { 2731 switch (mode) { 2732 case GAMEPORT_MODE_COOKED: 2733 return 0; 2734 case GAMEPORT_MODE_RAW: 2735 return 0; 2736 default: 2737 return -1; 2738 } 2739 return 0; 2740 } 2741 2742 int __devinit snd_cs46xx_gameport(cs46xx_t *chip) 2743 { 2744 struct gameport *gp; 2745 2746 chip->gameport = gp = gameport_allocate_port(); 2747 if (!gp) { 2748 printk(KERN_ERR "cs46xx: cannot allocate memory for gameport\n"); 2749 return -ENOMEM; 2750 } 2751 2752 gameport_set_name(gp, "CS46xx Gameport"); 2753 gameport_set_phys(gp, "pci%s/gameport0", pci_name(chip->pci)); 2754 gameport_set_dev_parent(gp, &chip->pci->dev); 2755 gameport_set_port_data(gp, chip); 2756 2757 gp->open = snd_cs46xx_gameport_open; 2758 gp->read = snd_cs46xx_gameport_read; 2759 gp->trigger = snd_cs46xx_gameport_trigger; 2760 gp->cooked_read = snd_cs46xx_gameport_cooked_read; 2761 2762 snd_cs46xx_pokeBA0(chip, BA0_JSIO, 0xFF); // ? 2763 snd_cs46xx_pokeBA0(chip, BA0_JSCTL, JSCTL_SP_MEDIUM_SLOW); 2764 2765 gameport_register_port(gp); 2766 2767 return 0; 2768 } 2769 2770 static inline void snd_cs46xx_remove_gameport(cs46xx_t *chip) 2771 { 2772 if (chip->gameport) { 2773 gameport_unregister_port(chip->gameport); 2774 chip->gameport = NULL; 2775 } 2776 } 2777 #else 2778 int __devinit snd_cs46xx_gameport(cs46xx_t *chip) { return -ENOSYS; } 2779 static inline void snd_cs46xx_remove_gameport(cs46xx_t *chip) { } 2780 #endif /* CONFIG_GAMEPORT */ 2781 2782 /* 2783 * proc interface 2784 */ 2785 2786 static long snd_cs46xx_io_read(snd_info_entry_t *entry, void *file_private_data, 2787 struct file *file, char __user *buf, 2788 unsigned long count, unsigned long pos) 2789 { 2790 long size; 2791 snd_cs46xx_region_t *region = (snd_cs46xx_region_t *)entry->private_data; 2792 2793 size = count; 2794 if (pos + (size_t)size > region->size) 2795 size = region->size - pos; 2796 if (size > 0) { 2797 if (copy_to_user_fromio(buf, region->remap_addr + pos, size)) 2798 return -EFAULT; 2799 } 2800 return size; 2801 } 2802 2803 static struct snd_info_entry_ops snd_cs46xx_proc_io_ops = { 2804 .read = snd_cs46xx_io_read, 2805 }; 2806 2807 static int __devinit snd_cs46xx_proc_init(snd_card_t * card, cs46xx_t *chip) 2808 { 2809 snd_info_entry_t *entry; 2810 int idx; 2811 2812 for (idx = 0; idx < 5; idx++) { 2813 snd_cs46xx_region_t *region = &chip->region.idx[idx]; 2814 if (! snd_card_proc_new(card, region->name, &entry)) { 2815 entry->content = SNDRV_INFO_CONTENT_DATA; 2816 entry->private_data = chip; 2817 entry->c.ops = &snd_cs46xx_proc_io_ops; 2818 entry->size = region->size; 2819 entry->mode = S_IFREG | S_IRUSR; 2820 } 2821 } 2822 #ifdef CONFIG_SND_CS46XX_NEW_DSP 2823 cs46xx_dsp_proc_init(card, chip); 2824 #endif 2825 return 0; 2826 } 2827 2828 static int snd_cs46xx_proc_done(cs46xx_t *chip) 2829 { 2830 #ifdef CONFIG_SND_CS46XX_NEW_DSP 2831 cs46xx_dsp_proc_done(chip); 2832 #endif 2833 return 0; 2834 } 2835 2836 /* 2837 * stop the h/w 2838 */ 2839 static void snd_cs46xx_hw_stop(cs46xx_t *chip) 2840 { 2841 unsigned int tmp; 2842 2843 tmp = snd_cs46xx_peek(chip, BA1_PFIE); 2844 tmp &= ~0x0000f03f; 2845 tmp |= 0x00000010; 2846 snd_cs46xx_poke(chip, BA1_PFIE, tmp); /* playback interrupt disable */ 2847 2848 tmp = snd_cs46xx_peek(chip, BA1_CIE); 2849 tmp &= ~0x0000003f; 2850 tmp |= 0x00000011; 2851 snd_cs46xx_poke(chip, BA1_CIE, tmp); /* capture interrupt disable */ 2852 2853 /* 2854 * Stop playback DMA. 2855 */ 2856 tmp = snd_cs46xx_peek(chip, BA1_PCTL); 2857 snd_cs46xx_poke(chip, BA1_PCTL, tmp & 0x0000ffff); 2858 2859 /* 2860 * Stop capture DMA. 2861 */ 2862 tmp = snd_cs46xx_peek(chip, BA1_CCTL); 2863 snd_cs46xx_poke(chip, BA1_CCTL, tmp & 0xffff0000); 2864 2865 /* 2866 * Reset the processor. 2867 */ 2868 snd_cs46xx_reset(chip); 2869 2870 snd_cs46xx_proc_stop(chip); 2871 2872 /* 2873 * Power down the PLL. 2874 */ 2875 snd_cs46xx_pokeBA0(chip, BA0_CLKCR1, 0); 2876 2877 /* 2878 * Turn off the Processor by turning off the software clock enable flag in 2879 * the clock control register. 2880 */ 2881 tmp = snd_cs46xx_peekBA0(chip, BA0_CLKCR1) & ~CLKCR1_SWCE; 2882 snd_cs46xx_pokeBA0(chip, BA0_CLKCR1, tmp); 2883 } 2884 2885 2886 static int snd_cs46xx_free(cs46xx_t *chip) 2887 { 2888 int idx; 2889 2890 snd_assert(chip != NULL, return -EINVAL); 2891 2892 if (chip->active_ctrl) 2893 chip->active_ctrl(chip, 1); 2894 2895 snd_cs46xx_remove_gameport(chip); 2896 2897 if (chip->amplifier_ctrl) 2898 chip->amplifier_ctrl(chip, -chip->amplifier); /* force to off */ 2899 2900 snd_cs46xx_proc_done(chip); 2901 2902 if (chip->region.idx[0].resource) 2903 snd_cs46xx_hw_stop(chip); 2904 2905 for (idx = 0; idx < 5; idx++) { 2906 snd_cs46xx_region_t *region = &chip->region.idx[idx]; 2907 if (region->remap_addr) 2908 iounmap(region->remap_addr); 2909 if (region->resource) { 2910 release_resource(region->resource); 2911 kfree_nocheck(region->resource); 2912 } 2913 } 2914 if (chip->irq >= 0) 2915 free_irq(chip->irq, (void *)chip); 2916 2917 if (chip->active_ctrl) 2918 chip->active_ctrl(chip, -chip->amplifier); 2919 2920 #ifdef CONFIG_SND_CS46XX_NEW_DSP 2921 if (chip->dsp_spos_instance) { 2922 cs46xx_dsp_spos_destroy(chip); 2923 chip->dsp_spos_instance = NULL; 2924 } 2925 #endif 2926 2927 pci_disable_device(chip->pci); 2928 kfree(chip); 2929 return 0; 2930 } 2931 2932 static int snd_cs46xx_dev_free(snd_device_t *device) 2933 { 2934 cs46xx_t *chip = device->device_data; 2935 return snd_cs46xx_free(chip); 2936 } 2937 2938 /* 2939 * initialize chip 2940 */ 2941 static int snd_cs46xx_chip_init(cs46xx_t *chip) 2942 { 2943 int timeout; 2944 2945 /* 2946 * First, blast the clock control register to zero so that the PLL starts 2947 * out in a known state, and blast the master serial port control register 2948 * to zero so that the serial ports also start out in a known state. 2949 */ 2950 snd_cs46xx_pokeBA0(chip, BA0_CLKCR1, 0); 2951 snd_cs46xx_pokeBA0(chip, BA0_SERMC1, 0); 2952 2953 /* 2954 * If we are in AC97 mode, then we must set the part to a host controlled 2955 * AC-link. Otherwise, we won't be able to bring up the link. 2956 */ 2957 #ifdef CONFIG_SND_CS46XX_NEW_DSP 2958 snd_cs46xx_pokeBA0(chip, BA0_SERACC, SERACC_HSP | SERACC_CHIP_TYPE_2_0 | 2959 SERACC_TWO_CODECS); /* 2.00 dual codecs */ 2960 /* snd_cs46xx_pokeBA0(chip, BA0_SERACC, SERACC_HSP | SERACC_CHIP_TYPE_2_0); */ /* 2.00 codec */ 2961 #else 2962 snd_cs46xx_pokeBA0(chip, BA0_SERACC, SERACC_HSP | SERACC_CHIP_TYPE_1_03); /* 1.03 codec */ 2963 #endif 2964 2965 /* 2966 * Drive the ARST# pin low for a minimum of 1uS (as defined in the AC97 2967 * spec) and then drive it high. This is done for non AC97 modes since 2968 * there might be logic external to the CS461x that uses the ARST# line 2969 * for a reset. 2970 */ 2971 snd_cs46xx_pokeBA0(chip, BA0_ACCTL, 0); 2972 #ifdef CONFIG_SND_CS46XX_NEW_DSP 2973 snd_cs46xx_pokeBA0(chip, BA0_ACCTL2, 0); 2974 #endif 2975 udelay(50); 2976 snd_cs46xx_pokeBA0(chip, BA0_ACCTL, ACCTL_RSTN); 2977 #ifdef CONFIG_SND_CS46XX_NEW_DSP 2978 snd_cs46xx_pokeBA0(chip, BA0_ACCTL2, ACCTL_RSTN); 2979 #endif 2980 2981 /* 2982 * The first thing we do here is to enable sync generation. As soon 2983 * as we start receiving bit clock, we'll start producing the SYNC 2984 * signal. 2985 */ 2986 snd_cs46xx_pokeBA0(chip, BA0_ACCTL, ACCTL_ESYN | ACCTL_RSTN); 2987 #ifdef CONFIG_SND_CS46XX_NEW_DSP 2988 snd_cs46xx_pokeBA0(chip, BA0_ACCTL2, ACCTL_ESYN | ACCTL_RSTN); 2989 #endif 2990 2991 /* 2992 * Now wait for a short while to allow the AC97 part to start 2993 * generating bit clock (so we don't try to start the PLL without an 2994 * input clock). 2995 */ 2996 mdelay(10); 2997 2998 /* 2999 * Set the serial port timing configuration, so that 3000 * the clock control circuit gets its clock from the correct place. 3001 */ 3002 snd_cs46xx_pokeBA0(chip, BA0_SERMC1, SERMC1_PTC_AC97); 3003 3004 /* 3005 * Write the selected clock control setup to the hardware. Do not turn on 3006 * SWCE yet (if requested), so that the devices clocked by the output of 3007 * PLL are not clocked until the PLL is stable. 3008 */ 3009 snd_cs46xx_pokeBA0(chip, BA0_PLLCC, PLLCC_LPF_1050_2780_KHZ | PLLCC_CDR_73_104_MHZ); 3010 snd_cs46xx_pokeBA0(chip, BA0_PLLM, 0x3a); 3011 snd_cs46xx_pokeBA0(chip, BA0_CLKCR2, CLKCR2_PDIVS_8); 3012 3013 /* 3014 * Power up the PLL. 3015 */ 3016 snd_cs46xx_pokeBA0(chip, BA0_CLKCR1, CLKCR1_PLLP); 3017 3018 /* 3019 * Wait until the PLL has stabilized. 3020 */ 3021 msleep(100); 3022 3023 /* 3024 * Turn on clocking of the core so that we can setup the serial ports. 3025 */ 3026 snd_cs46xx_pokeBA0(chip, BA0_CLKCR1, CLKCR1_PLLP | CLKCR1_SWCE); 3027 3028 /* 3029 * Enable FIFO Host Bypass 3030 */ 3031 snd_cs46xx_pokeBA0(chip, BA0_SERBCF, SERBCF_HBP); 3032 3033 /* 3034 * Fill the serial port FIFOs with silence. 3035 */ 3036 snd_cs46xx_clear_serial_FIFOs(chip); 3037 3038 /* 3039 * Set the serial port FIFO pointer to the first sample in the FIFO. 3040 */ 3041 /* snd_cs46xx_pokeBA0(chip, BA0_SERBSP, 0); */ 3042 3043 /* 3044 * Write the serial port configuration to the part. The master 3045 * enable bit is not set until all other values have been written. 3046 */ 3047 snd_cs46xx_pokeBA0(chip, BA0_SERC1, SERC1_SO1F_AC97 | SERC1_SO1EN); 3048 snd_cs46xx_pokeBA0(chip, BA0_SERC2, SERC2_SI1F_AC97 | SERC1_SO1EN); 3049 snd_cs46xx_pokeBA0(chip, BA0_SERMC1, SERMC1_PTC_AC97 | SERMC1_MSPE); 3050 3051 3052 #ifdef CONFIG_SND_CS46XX_NEW_DSP 3053 snd_cs46xx_pokeBA0(chip, BA0_SERC7, SERC7_ASDI2EN); 3054 snd_cs46xx_pokeBA0(chip, BA0_SERC3, 0); 3055 snd_cs46xx_pokeBA0(chip, BA0_SERC4, 0); 3056 snd_cs46xx_pokeBA0(chip, BA0_SERC5, 0); 3057 snd_cs46xx_pokeBA0(chip, BA0_SERC6, 1); 3058 #endif 3059 3060 mdelay(5); 3061 3062 3063 /* 3064 * Wait for the codec ready signal from the AC97 codec. 3065 */ 3066 timeout = 150; 3067 while (timeout-- > 0) { 3068 /* 3069 * Read the AC97 status register to see if we've seen a CODEC READY 3070 * signal from the AC97 codec. 3071 */ 3072 if (snd_cs46xx_peekBA0(chip, BA0_ACSTS) & ACSTS_CRDY) 3073 goto ok1; 3074 msleep(10); 3075 } 3076 3077 3078 snd_printk("create - never read codec ready from AC'97\n"); 3079 snd_printk("it is not probably bug, try to use CS4236 driver\n"); 3080 return -EIO; 3081 ok1: 3082 #ifdef CONFIG_SND_CS46XX_NEW_DSP 3083 { 3084 int count; 3085 for (count = 0; count < 150; count++) { 3086 /* First, we want to wait for a short time. */ 3087 udelay(25); 3088 3089 if (snd_cs46xx_peekBA0(chip, BA0_ACSTS2) & ACSTS_CRDY) 3090 break; 3091 } 3092 3093 /* 3094 * Make sure CODEC is READY. 3095 */ 3096 if (!(snd_cs46xx_peekBA0(chip, BA0_ACSTS2) & ACSTS_CRDY)) 3097 snd_printdd("cs46xx: never read card ready from secondary AC'97\n"); 3098 } 3099 #endif 3100 3101 /* 3102 * Assert the vaid frame signal so that we can start sending commands 3103 * to the AC97 codec. 3104 */ 3105 snd_cs46xx_pokeBA0(chip, BA0_ACCTL, ACCTL_VFRM | ACCTL_ESYN | ACCTL_RSTN); 3106 #ifdef CONFIG_SND_CS46XX_NEW_DSP 3107 snd_cs46xx_pokeBA0(chip, BA0_ACCTL2, ACCTL_VFRM | ACCTL_ESYN | ACCTL_RSTN); 3108 #endif 3109 3110 3111 /* 3112 * Wait until we've sampled input slots 3 and 4 as valid, meaning that 3113 * the codec is pumping ADC data across the AC-link. 3114 */ 3115 timeout = 150; 3116 while (timeout-- > 0) { 3117 /* 3118 * Read the input slot valid register and see if input slots 3 and 3119 * 4 are valid yet. 3120 */ 3121 if ((snd_cs46xx_peekBA0(chip, BA0_ACISV) & (ACISV_ISV3 | ACISV_ISV4)) == (ACISV_ISV3 | ACISV_ISV4)) 3122 goto ok2; 3123 msleep(10); 3124 } 3125 3126 #ifndef CONFIG_SND_CS46XX_NEW_DSP 3127 snd_printk("create - never read ISV3 & ISV4 from AC'97\n"); 3128 return -EIO; 3129 #else 3130 /* This may happen on a cold boot with a Terratec SiXPack 5.1. 3131 Reloading the driver may help, if there's other soundcards 3132 with the same problem I would like to know. (Benny) */ 3133 3134 snd_printk("ERROR: snd-cs46xx: never read ISV3 & ISV4 from AC'97\n"); 3135 snd_printk(" Try reloading the ALSA driver, if you find something\n"); 3136 snd_printk(" broken or not working on your soundcard upon\n"); 3137 snd_printk(" this message please report to alsa-devel@lists.sourceforge.net\n"); 3138 3139 return -EIO; 3140 #endif 3141 ok2: 3142 3143 /* 3144 * Now, assert valid frame and the slot 3 and 4 valid bits. This will 3145 * commense the transfer of digital audio data to the AC97 codec. 3146 */ 3147 3148 snd_cs46xx_pokeBA0(chip, BA0_ACOSV, ACOSV_SLV3 | ACOSV_SLV4); 3149 3150 3151 /* 3152 * Power down the DAC and ADC. We will power them up (if) when we need 3153 * them. 3154 */ 3155 /* snd_cs46xx_pokeBA0(chip, BA0_AC97_POWERDOWN, 0x300); */ 3156 3157 /* 3158 * Turn off the Processor by turning off the software clock enable flag in 3159 * the clock control register. 3160 */ 3161 /* tmp = snd_cs46xx_peekBA0(chip, BA0_CLKCR1) & ~CLKCR1_SWCE; */ 3162 /* snd_cs46xx_pokeBA0(chip, BA0_CLKCR1, tmp); */ 3163 3164 return 0; 3165 } 3166 3167 /* 3168 * start and load DSP 3169 */ 3170 int __devinit snd_cs46xx_start_dsp(cs46xx_t *chip) 3171 { 3172 unsigned int tmp; 3173 /* 3174 * Reset the processor. 3175 */ 3176 snd_cs46xx_reset(chip); 3177 /* 3178 * Download the image to the processor. 3179 */ 3180 #ifdef CONFIG_SND_CS46XX_NEW_DSP 3181 #if 0 3182 if (cs46xx_dsp_load_module(chip, &cwcemb80_module) < 0) { 3183 snd_printk(KERN_ERR "image download error\n"); 3184 return -EIO; 3185 } 3186 #endif 3187 3188 if (cs46xx_dsp_load_module(chip, &cwc4630_module) < 0) { 3189 snd_printk(KERN_ERR "image download error [cwc4630]\n"); 3190 return -EIO; 3191 } 3192 3193 if (cs46xx_dsp_load_module(chip, &cwcasync_module) < 0) { 3194 snd_printk(KERN_ERR "image download error [cwcasync]\n"); 3195 return -EIO; 3196 } 3197 3198 if (cs46xx_dsp_load_module(chip, &cwcsnoop_module) < 0) { 3199 snd_printk(KERN_ERR "image download error [cwcsnoop]\n"); 3200 return -EIO; 3201 } 3202 3203 if (cs46xx_dsp_load_module(chip, &cwcbinhack_module) < 0) { 3204 snd_printk(KERN_ERR "image download error [cwcbinhack]\n"); 3205 return -EIO; 3206 } 3207 3208 if (cs46xx_dsp_load_module(chip, &cwcdma_module) < 0) { 3209 snd_printk(KERN_ERR "image download error [cwcdma]\n"); 3210 return -EIO; 3211 } 3212 3213 if (cs46xx_dsp_scb_and_task_init(chip) < 0) 3214 return -EIO; 3215 #else 3216 /* old image */ 3217 if (snd_cs46xx_download_image(chip) < 0) { 3218 snd_printk("image download error\n"); 3219 return -EIO; 3220 } 3221 3222 /* 3223 * Stop playback DMA. 3224 */ 3225 tmp = snd_cs46xx_peek(chip, BA1_PCTL); 3226 chip->play_ctl = tmp & 0xffff0000; 3227 snd_cs46xx_poke(chip, BA1_PCTL, tmp & 0x0000ffff); 3228 #endif 3229 3230 /* 3231 * Stop capture DMA. 3232 */ 3233 tmp = snd_cs46xx_peek(chip, BA1_CCTL); 3234 chip->capt.ctl = tmp & 0x0000ffff; 3235 snd_cs46xx_poke(chip, BA1_CCTL, tmp & 0xffff0000); 3236 3237 mdelay(5); 3238 3239 snd_cs46xx_set_play_sample_rate(chip, 8000); 3240 snd_cs46xx_set_capture_sample_rate(chip, 8000); 3241 3242 snd_cs46xx_proc_start(chip); 3243 3244 /* 3245 * Enable interrupts on the part. 3246 */ 3247 snd_cs46xx_pokeBA0(chip, BA0_HICR, HICR_IEV | HICR_CHGM); 3248 3249 tmp = snd_cs46xx_peek(chip, BA1_PFIE); 3250 tmp &= ~0x0000f03f; 3251 snd_cs46xx_poke(chip, BA1_PFIE, tmp); /* playback interrupt enable */ 3252 3253 tmp = snd_cs46xx_peek(chip, BA1_CIE); 3254 tmp &= ~0x0000003f; 3255 tmp |= 0x00000001; 3256 snd_cs46xx_poke(chip, BA1_CIE, tmp); /* capture interrupt enable */ 3257 3258 #ifndef CONFIG_SND_CS46XX_NEW_DSP 3259 /* set the attenuation to 0dB */ 3260 snd_cs46xx_poke(chip, BA1_PVOL, 0x80008000); 3261 snd_cs46xx_poke(chip, BA1_CVOL, 0x80008000); 3262 #endif 3263 3264 return 0; 3265 } 3266 3267 3268 /* 3269 * AMP control - null AMP 3270 */ 3271 3272 static void amp_none(cs46xx_t *chip, int change) 3273 { 3274 } 3275 3276 #ifdef CONFIG_SND_CS46XX_NEW_DSP 3277 static int voyetra_setup_eapd_slot(cs46xx_t *chip) 3278 { 3279 3280 u32 idx, valid_slots,tmp,powerdown = 0; 3281 u16 modem_power,pin_config,logic_type; 3282 3283 snd_printdd ("cs46xx: cs46xx_setup_eapd_slot()+\n"); 3284 3285 /* 3286 * See if the devices are powered down. If so, we must power them up first 3287 * or they will not respond. 3288 */ 3289 tmp = snd_cs46xx_peekBA0(chip, BA0_CLKCR1); 3290 3291 if (!(tmp & CLKCR1_SWCE)) { 3292 snd_cs46xx_pokeBA0(chip, BA0_CLKCR1, tmp | CLKCR1_SWCE); 3293 powerdown = 1; 3294 } 3295 3296 /* 3297 * Clear PRA. The Bonzo chip will be used for GPIO not for modem 3298 * stuff. 3299 */ 3300 if(chip->nr_ac97_codecs != 2) { 3301 snd_printk (KERN_ERR "cs46xx: cs46xx_setup_eapd_slot() - no secondary codec configured\n"); 3302 return -EINVAL; 3303 } 3304 3305 modem_power = snd_cs46xx_codec_read (chip, 3306 AC97_EXTENDED_MSTATUS, 3307 CS46XX_SECONDARY_CODEC_INDEX); 3308 modem_power &=0xFEFF; 3309 3310 snd_cs46xx_codec_write(chip, 3311 AC97_EXTENDED_MSTATUS, modem_power, 3312 CS46XX_SECONDARY_CODEC_INDEX); 3313 3314 /* 3315 * Set GPIO pin's 7 and 8 so that they are configured for output. 3316 */ 3317 pin_config = snd_cs46xx_codec_read (chip, 3318 AC97_GPIO_CFG, 3319 CS46XX_SECONDARY_CODEC_INDEX); 3320 pin_config &=0x27F; 3321 3322 snd_cs46xx_codec_write(chip, 3323 AC97_GPIO_CFG, pin_config, 3324 CS46XX_SECONDARY_CODEC_INDEX); 3325 3326 /* 3327 * Set GPIO pin's 7 and 8 so that they are compatible with CMOS logic. 3328 */ 3329 3330 logic_type = snd_cs46xx_codec_read(chip, AC97_GPIO_POLARITY, 3331 CS46XX_SECONDARY_CODEC_INDEX); 3332 logic_type &=0x27F; 3333 3334 snd_cs46xx_codec_write (chip, AC97_GPIO_POLARITY, logic_type, 3335 CS46XX_SECONDARY_CODEC_INDEX); 3336 3337 valid_slots = snd_cs46xx_peekBA0(chip, BA0_ACOSV); 3338 valid_slots |= 0x200; 3339 snd_cs46xx_pokeBA0(chip, BA0_ACOSV, valid_slots); 3340 3341 if ( cs46xx_wait_for_fifo(chip,1) ) { 3342 snd_printdd("FIFO is busy\n"); 3343 3344 return -EINVAL; 3345 } 3346 3347 /* 3348 * Fill slots 12 with the correct value for the GPIO pins. 3349 */ 3350 for(idx = 0x90; idx <= 0x9F; idx++) { 3351 /* 3352 * Initialize the fifo so that bits 7 and 8 are on. 3353 * 3354 * Remember that the GPIO pins in bonzo are shifted by 4 bits to 3355 * the left. 0x1800 corresponds to bits 7 and 8. 3356 */ 3357 snd_cs46xx_pokeBA0(chip, BA0_SERBWP, 0x1800); 3358 3359 /* 3360 * Wait for command to complete 3361 */ 3362 if ( cs46xx_wait_for_fifo(chip,200) ) { 3363 snd_printdd("failed waiting for FIFO at addr (%02X)\n",idx); 3364 3365 return -EINVAL; 3366 } 3367 3368 /* 3369 * Write the serial port FIFO index. 3370 */ 3371 snd_cs46xx_pokeBA0(chip, BA0_SERBAD, idx); 3372 3373 /* 3374 * Tell the serial port to load the new value into the FIFO location. 3375 */ 3376 snd_cs46xx_pokeBA0(chip, BA0_SERBCM, SERBCM_WRC); 3377 } 3378 3379 /* wait for last command to complete */ 3380 cs46xx_wait_for_fifo(chip,200); 3381 3382 /* 3383 * Now, if we powered up the devices, then power them back down again. 3384 * This is kinda ugly, but should never happen. 3385 */ 3386 if (powerdown) 3387 snd_cs46xx_pokeBA0(chip, BA0_CLKCR1, tmp); 3388 3389 return 0; 3390 } 3391 #endif 3392 3393 /* 3394 * Crystal EAPD mode 3395 */ 3396 3397 static void amp_voyetra(cs46xx_t *chip, int change) 3398 { 3399 /* Manage the EAPD bit on the Crystal 4297 3400 and the Analog AD1885 */ 3401 3402 #ifdef CONFIG_SND_CS46XX_NEW_DSP 3403 int old = chip->amplifier; 3404 #endif 3405 int oval, val; 3406 3407 chip->amplifier += change; 3408 oval = snd_cs46xx_codec_read(chip, AC97_POWERDOWN, 3409 CS46XX_PRIMARY_CODEC_INDEX); 3410 val = oval; 3411 if (chip->amplifier) { 3412 /* Turn the EAPD amp on */ 3413 val |= 0x8000; 3414 } else { 3415 /* Turn the EAPD amp off */ 3416 val &= ~0x8000; 3417 } 3418 if (val != oval) { 3419 snd_cs46xx_codec_write(chip, AC97_POWERDOWN, val, 3420 CS46XX_PRIMARY_CODEC_INDEX); 3421 if (chip->eapd_switch) 3422 snd_ctl_notify(chip->card, SNDRV_CTL_EVENT_MASK_VALUE, 3423 &chip->eapd_switch->id); 3424 } 3425 3426 #ifdef CONFIG_SND_CS46XX_NEW_DSP 3427 if (chip->amplifier && !old) { 3428 voyetra_setup_eapd_slot(chip); 3429 } 3430 #endif 3431 } 3432 3433 static void hercules_init(cs46xx_t *chip) 3434 { 3435 /* default: AMP off, and SPDIF input optical */ 3436 snd_cs46xx_pokeBA0(chip, BA0_EGPIODR, EGPIODR_GPOE0); 3437 snd_cs46xx_pokeBA0(chip, BA0_EGPIOPTR, EGPIODR_GPOE0); 3438 } 3439 3440 3441 /* 3442 * Game Theatre XP card - EGPIO[2] is used to enable the external amp. 3443 */ 3444 static void amp_hercules(cs46xx_t *chip, int change) 3445 { 3446 int old = chip->amplifier; 3447 int val1 = snd_cs46xx_peekBA0(chip, BA0_EGPIODR); 3448 int val2 = snd_cs46xx_peekBA0(chip, BA0_EGPIOPTR); 3449 3450 chip->amplifier += change; 3451 if (chip->amplifier && !old) { 3452 snd_printdd ("Hercules amplifier ON\n"); 3453 3454 snd_cs46xx_pokeBA0(chip, BA0_EGPIODR, 3455 EGPIODR_GPOE2 | val1); /* enable EGPIO2 output */ 3456 snd_cs46xx_pokeBA0(chip, BA0_EGPIOPTR, 3457 EGPIOPTR_GPPT2 | val2); /* open-drain on output */ 3458 } else if (old && !chip->amplifier) { 3459 snd_printdd ("Hercules amplifier OFF\n"); 3460 snd_cs46xx_pokeBA0(chip, BA0_EGPIODR, val1 & ~EGPIODR_GPOE2); /* disable */ 3461 snd_cs46xx_pokeBA0(chip, BA0_EGPIOPTR, val2 & ~EGPIOPTR_GPPT2); /* disable */ 3462 } 3463 } 3464 3465 static void voyetra_mixer_init (cs46xx_t *chip) 3466 { 3467 snd_printdd ("initializing Voyetra mixer\n"); 3468 3469 /* Enable SPDIF out */ 3470 snd_cs46xx_pokeBA0(chip, BA0_EGPIODR, EGPIODR_GPOE0); 3471 snd_cs46xx_pokeBA0(chip, BA0_EGPIOPTR, EGPIODR_GPOE0); 3472 } 3473 3474 static void hercules_mixer_init (cs46xx_t *chip) 3475 { 3476 #ifdef CONFIG_SND_CS46XX_NEW_DSP 3477 unsigned int idx; 3478 int err; 3479 snd_card_t *card = chip->card; 3480 #endif 3481 3482 /* set EGPIO to default */ 3483 hercules_init(chip); 3484 3485 snd_printdd ("initializing Hercules mixer\n"); 3486 3487 #ifdef CONFIG_SND_CS46XX_NEW_DSP 3488 for (idx = 0 ; idx < ARRAY_SIZE(snd_hercules_controls); idx++) { 3489 snd_kcontrol_t *kctl; 3490 3491 kctl = snd_ctl_new1(&snd_hercules_controls[idx], chip); 3492 if ((err = snd_ctl_add(card, kctl)) < 0) { 3493 printk (KERN_ERR "cs46xx: failed to initialize Hercules mixer (%d)\n",err); 3494 break; 3495 } 3496 } 3497 #endif 3498 } 3499 3500 3501 #if 0 3502 /* 3503 * Untested 3504 */ 3505 3506 static void amp_voyetra_4294(cs46xx_t *chip, int change) 3507 { 3508 chip->amplifier += change; 3509 3510 if (chip->amplifier) { 3511 /* Switch the GPIO pins 7 and 8 to open drain */ 3512 snd_cs46xx_codec_write(chip, 0x4C, 3513 snd_cs46xx_codec_read(chip, 0x4C) & 0xFE7F); 3514 snd_cs46xx_codec_write(chip, 0x4E, 3515 snd_cs46xx_codec_read(chip, 0x4E) | 0x0180); 3516 /* Now wake the AMP (this might be backwards) */ 3517 snd_cs46xx_codec_write(chip, 0x54, 3518 snd_cs46xx_codec_read(chip, 0x54) & ~0x0180); 3519 } else { 3520 snd_cs46xx_codec_write(chip, 0x54, 3521 snd_cs46xx_codec_read(chip, 0x54) | 0x0180); 3522 } 3523 } 3524 #endif 3525 3526 3527 /* 3528 * piix4 pci ids 3529 */ 3530 #ifndef PCI_VENDOR_ID_INTEL 3531 #define PCI_VENDOR_ID_INTEL 0x8086 3532 #endif /* PCI_VENDOR_ID_INTEL */ 3533 3534 #ifndef PCI_DEVICE_ID_INTEL_82371AB_3 3535 #define PCI_DEVICE_ID_INTEL_82371AB_3 0x7113 3536 #endif /* PCI_DEVICE_ID_INTEL_82371AB_3 */ 3537 3538 /* 3539 * Handle the CLKRUN on a thinkpad. We must disable CLKRUN support 3540 * whenever we need to beat on the chip. 3541 * 3542 * The original idea and code for this hack comes from David Kaiser at 3543 * Linuxcare. Perhaps one day Crystal will document their chips well 3544 * enough to make them useful. 3545 */ 3546 3547 static void clkrun_hack(cs46xx_t *chip, int change) 3548 { 3549 u16 control, nval; 3550 3551 if (chip->acpi_dev == NULL) 3552 return; 3553 3554 chip->amplifier += change; 3555 3556 /* Read ACPI port */ 3557 nval = control = inw(chip->acpi_port + 0x10); 3558 3559 /* Flip CLKRUN off while running */ 3560 if (! chip->amplifier) 3561 nval |= 0x2000; 3562 else 3563 nval &= ~0x2000; 3564 if (nval != control) 3565 outw(nval, chip->acpi_port + 0x10); 3566 } 3567 3568 3569 /* 3570 * detect intel piix4 3571 */ 3572 static void clkrun_init(cs46xx_t *chip) 3573 { 3574 u8 pp; 3575 3576 chip->acpi_dev = pci_find_device(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82371AB_3, NULL); 3577 if (chip->acpi_dev == NULL) 3578 return; /* Not a thinkpad thats for sure */ 3579 3580 /* Find the control port */ 3581 pci_read_config_byte(chip->acpi_dev, 0x41, &pp); 3582 chip->acpi_port = pp << 8; 3583 } 3584 3585 3586 /* 3587 * Card subid table 3588 */ 3589 3590 struct cs_card_type 3591 { 3592 u16 vendor; 3593 u16 id; 3594 char *name; 3595 void (*init)(cs46xx_t *); 3596 void (*amp)(cs46xx_t *, int); 3597 void (*active)(cs46xx_t *, int); 3598 void (*mixer_init)(cs46xx_t *); 3599 }; 3600 3601 static struct cs_card_type __devinitdata cards[] = { 3602 { 3603 .vendor = 0x1489, 3604 .id = 0x7001, 3605 .name = "Genius Soundmaker 128 value", 3606 /* nothing special */ 3607 }, 3608 { 3609 .vendor = 0x5053, 3610 .id = 0x3357, 3611 .name = "Voyetra", 3612 .amp = amp_voyetra, 3613 .mixer_init = voyetra_mixer_init, 3614 }, 3615 { 3616 .vendor = 0x1071, 3617 .id = 0x6003, 3618 .name = "Mitac MI6020/21", 3619 .amp = amp_voyetra, 3620 }, 3621 { 3622 .vendor = 0x14AF, 3623 .id = 0x0050, 3624 .name = "Hercules Game Theatre XP", 3625 .amp = amp_hercules, 3626 .mixer_init = hercules_mixer_init, 3627 }, 3628 { 3629 .vendor = 0x1681, 3630 .id = 0x0050, 3631 .name = "Hercules Game Theatre XP", 3632 .amp = amp_hercules, 3633 .mixer_init = hercules_mixer_init, 3634 }, 3635 { 3636 .vendor = 0x1681, 3637 .id = 0x0051, 3638 .name = "Hercules Game Theatre XP", 3639 .amp = amp_hercules, 3640 .mixer_init = hercules_mixer_init, 3641 3642 }, 3643 { 3644 .vendor = 0x1681, 3645 .id = 0x0052, 3646 .name = "Hercules Game Theatre XP", 3647 .amp = amp_hercules, 3648 .mixer_init = hercules_mixer_init, 3649 }, 3650 { 3651 .vendor = 0x1681, 3652 .id = 0x0053, 3653 .name = "Hercules Game Theatre XP", 3654 .amp = amp_hercules, 3655 .mixer_init = hercules_mixer_init, 3656 }, 3657 { 3658 .vendor = 0x1681, 3659 .id = 0x0054, 3660 .name = "Hercules Game Theatre XP", 3661 .amp = amp_hercules, 3662 .mixer_init = hercules_mixer_init, 3663 }, 3664 /* Teratec */ 3665 { 3666 .vendor = 0x153b, 3667 .id = 0x1136, 3668 .name = "Terratec SiXPack 5.1", 3669 }, 3670 /* Not sure if the 570 needs the clkrun hack */ 3671 { 3672 .vendor = PCI_VENDOR_ID_IBM, 3673 .id = 0x0132, 3674 .name = "Thinkpad 570", 3675 .init = clkrun_init, 3676 .active = clkrun_hack, 3677 }, 3678 { 3679 .vendor = PCI_VENDOR_ID_IBM, 3680 .id = 0x0153, 3681 .name = "Thinkpad 600X/A20/T20", 3682 .init = clkrun_init, 3683 .active = clkrun_hack, 3684 }, 3685 { 3686 .vendor = PCI_VENDOR_ID_IBM, 3687 .id = 0x1010, 3688 .name = "Thinkpad 600E (unsupported)", 3689 }, 3690 {} /* terminator */ 3691 }; 3692 3693 3694 /* 3695 * APM support 3696 */ 3697 #ifdef CONFIG_PM 3698 static int snd_cs46xx_suspend(snd_card_t *card, pm_message_t state) 3699 { 3700 cs46xx_t *chip = card->pm_private_data; 3701 int amp_saved; 3702 3703 snd_pcm_suspend_all(chip->pcm); 3704 // chip->ac97_powerdown = snd_cs46xx_codec_read(chip, AC97_POWER_CONTROL); 3705 // chip->ac97_general_purpose = snd_cs46xx_codec_read(chip, BA0_AC97_GENERAL_PURPOSE); 3706 3707 snd_ac97_suspend(chip->ac97[CS46XX_PRIMARY_CODEC_INDEX]); 3708 if (chip->ac97[CS46XX_SECONDARY_CODEC_INDEX]) 3709 snd_ac97_suspend(chip->ac97[CS46XX_SECONDARY_CODEC_INDEX]); 3710 3711 amp_saved = chip->amplifier; 3712 /* turn off amp */ 3713 chip->amplifier_ctrl(chip, -chip->amplifier); 3714 snd_cs46xx_hw_stop(chip); 3715 /* disable CLKRUN */ 3716 chip->active_ctrl(chip, -chip->amplifier); 3717 chip->amplifier = amp_saved; /* restore the status */ 3718 pci_disable_device(chip->pci); 3719 return 0; 3720 } 3721 3722 static int snd_cs46xx_resume(snd_card_t *card) 3723 { 3724 cs46xx_t *chip = card->pm_private_data; 3725 int amp_saved; 3726 3727 pci_enable_device(chip->pci); 3728 pci_set_master(chip->pci); 3729 amp_saved = chip->amplifier; 3730 chip->amplifier = 0; 3731 chip->active_ctrl(chip, 1); /* force to on */ 3732 3733 snd_cs46xx_chip_init(chip); 3734 3735 #if 0 3736 snd_cs46xx_codec_write(chip, BA0_AC97_GENERAL_PURPOSE, 3737 chip->ac97_general_purpose); 3738 snd_cs46xx_codec_write(chip, AC97_POWER_CONTROL, 3739 chip->ac97_powerdown); 3740 mdelay(10); 3741 snd_cs46xx_codec_write(chip, BA0_AC97_POWERDOWN, 3742 chip->ac97_powerdown); 3743 mdelay(5); 3744 #endif 3745 3746 snd_ac97_resume(chip->ac97[CS46XX_PRIMARY_CODEC_INDEX]); 3747 if (chip->ac97[CS46XX_SECONDARY_CODEC_INDEX]) 3748 snd_ac97_resume(chip->ac97[CS46XX_SECONDARY_CODEC_INDEX]); 3749 3750 if (amp_saved) 3751 chip->amplifier_ctrl(chip, 1); /* turn amp on */ 3752 else 3753 chip->active_ctrl(chip, -1); /* disable CLKRUN */ 3754 chip->amplifier = amp_saved; 3755 return 0; 3756 } 3757 #endif /* CONFIG_PM */ 3758 3759 3760 /* 3761 */ 3762 3763 int __devinit snd_cs46xx_create(snd_card_t * card, 3764 struct pci_dev * pci, 3765 int external_amp, int thinkpad, 3766 cs46xx_t ** rchip) 3767 { 3768 cs46xx_t *chip; 3769 int err, idx; 3770 snd_cs46xx_region_t *region; 3771 struct cs_card_type *cp; 3772 u16 ss_card, ss_vendor; 3773 static snd_device_ops_t ops = { 3774 .dev_free = snd_cs46xx_dev_free, 3775 }; 3776 3777 *rchip = NULL; 3778 3779 /* enable PCI device */ 3780 if ((err = pci_enable_device(pci)) < 0) 3781 return err; 3782 3783 chip = kcalloc(1, sizeof(*chip), GFP_KERNEL); 3784 if (chip == NULL) { 3785 pci_disable_device(pci); 3786 return -ENOMEM; 3787 } 3788 spin_lock_init(&chip->reg_lock); 3789 #ifdef CONFIG_SND_CS46XX_NEW_DSP 3790 init_MUTEX(&chip->spos_mutex); 3791 #endif 3792 chip->card = card; 3793 chip->pci = pci; 3794 chip->irq = -1; 3795 chip->ba0_addr = pci_resource_start(pci, 0); 3796 chip->ba1_addr = pci_resource_start(pci, 1); 3797 if (chip->ba0_addr == 0 || chip->ba0_addr == (unsigned long)~0 || 3798 chip->ba1_addr == 0 || chip->ba1_addr == (unsigned long)~0) { 3799 snd_printk("wrong address(es) - ba0 = 0x%lx, ba1 = 0x%lx\n", chip->ba0_addr, chip->ba1_addr); 3800 snd_cs46xx_free(chip); 3801 return -ENOMEM; 3802 } 3803 3804 region = &chip->region.name.ba0; 3805 strcpy(region->name, "CS46xx_BA0"); 3806 region->base = chip->ba0_addr; 3807 region->size = CS46XX_BA0_SIZE; 3808 3809 region = &chip->region.name.data0; 3810 strcpy(region->name, "CS46xx_BA1_data0"); 3811 region->base = chip->ba1_addr + BA1_SP_DMEM0; 3812 region->size = CS46XX_BA1_DATA0_SIZE; 3813 3814 region = &chip->region.name.data1; 3815 strcpy(region->name, "CS46xx_BA1_data1"); 3816 region->base = chip->ba1_addr + BA1_SP_DMEM1; 3817 region->size = CS46XX_BA1_DATA1_SIZE; 3818 3819 region = &chip->region.name.pmem; 3820 strcpy(region->name, "CS46xx_BA1_pmem"); 3821 region->base = chip->ba1_addr + BA1_SP_PMEM; 3822 region->size = CS46XX_BA1_PRG_SIZE; 3823 3824 region = &chip->region.name.reg; 3825 strcpy(region->name, "CS46xx_BA1_reg"); 3826 region->base = chip->ba1_addr + BA1_SP_REG; 3827 region->size = CS46XX_BA1_REG_SIZE; 3828 3829 /* set up amp and clkrun hack */ 3830 pci_read_config_word(pci, PCI_SUBSYSTEM_VENDOR_ID, &ss_vendor); 3831 pci_read_config_word(pci, PCI_SUBSYSTEM_ID, &ss_card); 3832 3833 for (cp = &cards[0]; cp->name; cp++) { 3834 if (cp->vendor == ss_vendor && cp->id == ss_card) { 3835 snd_printdd ("hack for %s enabled\n", cp->name); 3836 3837 chip->amplifier_ctrl = cp->amp; 3838 chip->active_ctrl = cp->active; 3839 chip->mixer_init = cp->mixer_init; 3840 3841 if (cp->init) 3842 cp->init(chip); 3843 break; 3844 } 3845 } 3846 3847 if (external_amp) { 3848 snd_printk("Crystal EAPD support forced on.\n"); 3849 chip->amplifier_ctrl = amp_voyetra; 3850 } 3851 3852 if (thinkpad) { 3853 snd_printk("Activating CLKRUN hack for Thinkpad.\n"); 3854 chip->active_ctrl = clkrun_hack; 3855 clkrun_init(chip); 3856 } 3857 3858 if (chip->amplifier_ctrl == NULL) 3859 chip->amplifier_ctrl = amp_none; 3860 if (chip->active_ctrl == NULL) 3861 chip->active_ctrl = amp_none; 3862 3863 chip->active_ctrl(chip, 1); /* enable CLKRUN */ 3864 3865 pci_set_master(pci); 3866 3867 for (idx = 0; idx < 5; idx++) { 3868 region = &chip->region.idx[idx]; 3869 if ((region->resource = request_mem_region(region->base, region->size, region->name)) == NULL) { 3870 snd_printk("unable to request memory region 0x%lx-0x%lx\n", region->base, region->base + region->size - 1); 3871 snd_cs46xx_free(chip); 3872 return -EBUSY; 3873 } 3874 region->remap_addr = ioremap_nocache(region->base, region->size); 3875 if (region->remap_addr == NULL) { 3876 snd_printk("%s ioremap problem\n", region->name); 3877 snd_cs46xx_free(chip); 3878 return -ENOMEM; 3879 } 3880 } 3881 3882 if (request_irq(pci->irq, snd_cs46xx_interrupt, SA_INTERRUPT|SA_SHIRQ, "CS46XX", (void *) chip)) { 3883 snd_printk("unable to grab IRQ %d\n", pci->irq); 3884 snd_cs46xx_free(chip); 3885 return -EBUSY; 3886 } 3887 chip->irq = pci->irq; 3888 3889 #ifdef CONFIG_SND_CS46XX_NEW_DSP 3890 chip->dsp_spos_instance = cs46xx_dsp_spos_create(chip); 3891 if (chip->dsp_spos_instance == NULL) { 3892 snd_cs46xx_free(chip); 3893 return -ENOMEM; 3894 } 3895 #endif 3896 3897 err = snd_cs46xx_chip_init(chip); 3898 if (err < 0) { 3899 snd_cs46xx_free(chip); 3900 return err; 3901 } 3902 3903 if ((err = snd_device_new(card, SNDRV_DEV_LOWLEVEL, chip, &ops)) < 0) { 3904 snd_cs46xx_free(chip); 3905 return err; 3906 } 3907 3908 snd_cs46xx_proc_init(card, chip); 3909 3910 snd_card_set_pm_callback(card, snd_cs46xx_suspend, snd_cs46xx_resume, chip); 3911 3912 chip->active_ctrl(chip, -1); /* disable CLKRUN */ 3913 3914 snd_card_set_dev(card, &pci->dev); 3915 3916 *rchip = chip; 3917 return 0; 3918 } 3919