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(KERN_ERR "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(KERN_ERR "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(KERN_ERR "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(KERN_ERR "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 = kzalloc(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(KERN_ERR "CS46xx secondary codec doesn't 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 release_and_free_resource(region->resource); 2910 } 2911 if (chip->irq >= 0) 2912 free_irq(chip->irq, (void *)chip); 2913 2914 if (chip->active_ctrl) 2915 chip->active_ctrl(chip, -chip->amplifier); 2916 2917 #ifdef CONFIG_SND_CS46XX_NEW_DSP 2918 if (chip->dsp_spos_instance) { 2919 cs46xx_dsp_spos_destroy(chip); 2920 chip->dsp_spos_instance = NULL; 2921 } 2922 #endif 2923 2924 pci_disable_device(chip->pci); 2925 kfree(chip); 2926 return 0; 2927 } 2928 2929 static int snd_cs46xx_dev_free(snd_device_t *device) 2930 { 2931 cs46xx_t *chip = device->device_data; 2932 return snd_cs46xx_free(chip); 2933 } 2934 2935 /* 2936 * initialize chip 2937 */ 2938 static int snd_cs46xx_chip_init(cs46xx_t *chip) 2939 { 2940 int timeout; 2941 2942 /* 2943 * First, blast the clock control register to zero so that the PLL starts 2944 * out in a known state, and blast the master serial port control register 2945 * to zero so that the serial ports also start out in a known state. 2946 */ 2947 snd_cs46xx_pokeBA0(chip, BA0_CLKCR1, 0); 2948 snd_cs46xx_pokeBA0(chip, BA0_SERMC1, 0); 2949 2950 /* 2951 * If we are in AC97 mode, then we must set the part to a host controlled 2952 * AC-link. Otherwise, we won't be able to bring up the link. 2953 */ 2954 #ifdef CONFIG_SND_CS46XX_NEW_DSP 2955 snd_cs46xx_pokeBA0(chip, BA0_SERACC, SERACC_HSP | SERACC_CHIP_TYPE_2_0 | 2956 SERACC_TWO_CODECS); /* 2.00 dual codecs */ 2957 /* snd_cs46xx_pokeBA0(chip, BA0_SERACC, SERACC_HSP | SERACC_CHIP_TYPE_2_0); */ /* 2.00 codec */ 2958 #else 2959 snd_cs46xx_pokeBA0(chip, BA0_SERACC, SERACC_HSP | SERACC_CHIP_TYPE_1_03); /* 1.03 codec */ 2960 #endif 2961 2962 /* 2963 * Drive the ARST# pin low for a minimum of 1uS (as defined in the AC97 2964 * spec) and then drive it high. This is done for non AC97 modes since 2965 * there might be logic external to the CS461x that uses the ARST# line 2966 * for a reset. 2967 */ 2968 snd_cs46xx_pokeBA0(chip, BA0_ACCTL, 0); 2969 #ifdef CONFIG_SND_CS46XX_NEW_DSP 2970 snd_cs46xx_pokeBA0(chip, BA0_ACCTL2, 0); 2971 #endif 2972 udelay(50); 2973 snd_cs46xx_pokeBA0(chip, BA0_ACCTL, ACCTL_RSTN); 2974 #ifdef CONFIG_SND_CS46XX_NEW_DSP 2975 snd_cs46xx_pokeBA0(chip, BA0_ACCTL2, ACCTL_RSTN); 2976 #endif 2977 2978 /* 2979 * The first thing we do here is to enable sync generation. As soon 2980 * as we start receiving bit clock, we'll start producing the SYNC 2981 * signal. 2982 */ 2983 snd_cs46xx_pokeBA0(chip, BA0_ACCTL, ACCTL_ESYN | ACCTL_RSTN); 2984 #ifdef CONFIG_SND_CS46XX_NEW_DSP 2985 snd_cs46xx_pokeBA0(chip, BA0_ACCTL2, ACCTL_ESYN | ACCTL_RSTN); 2986 #endif 2987 2988 /* 2989 * Now wait for a short while to allow the AC97 part to start 2990 * generating bit clock (so we don't try to start the PLL without an 2991 * input clock). 2992 */ 2993 mdelay(10); 2994 2995 /* 2996 * Set the serial port timing configuration, so that 2997 * the clock control circuit gets its clock from the correct place. 2998 */ 2999 snd_cs46xx_pokeBA0(chip, BA0_SERMC1, SERMC1_PTC_AC97); 3000 3001 /* 3002 * Write the selected clock control setup to the hardware. Do not turn on 3003 * SWCE yet (if requested), so that the devices clocked by the output of 3004 * PLL are not clocked until the PLL is stable. 3005 */ 3006 snd_cs46xx_pokeBA0(chip, BA0_PLLCC, PLLCC_LPF_1050_2780_KHZ | PLLCC_CDR_73_104_MHZ); 3007 snd_cs46xx_pokeBA0(chip, BA0_PLLM, 0x3a); 3008 snd_cs46xx_pokeBA0(chip, BA0_CLKCR2, CLKCR2_PDIVS_8); 3009 3010 /* 3011 * Power up the PLL. 3012 */ 3013 snd_cs46xx_pokeBA0(chip, BA0_CLKCR1, CLKCR1_PLLP); 3014 3015 /* 3016 * Wait until the PLL has stabilized. 3017 */ 3018 msleep(100); 3019 3020 /* 3021 * Turn on clocking of the core so that we can setup the serial ports. 3022 */ 3023 snd_cs46xx_pokeBA0(chip, BA0_CLKCR1, CLKCR1_PLLP | CLKCR1_SWCE); 3024 3025 /* 3026 * Enable FIFO Host Bypass 3027 */ 3028 snd_cs46xx_pokeBA0(chip, BA0_SERBCF, SERBCF_HBP); 3029 3030 /* 3031 * Fill the serial port FIFOs with silence. 3032 */ 3033 snd_cs46xx_clear_serial_FIFOs(chip); 3034 3035 /* 3036 * Set the serial port FIFO pointer to the first sample in the FIFO. 3037 */ 3038 /* snd_cs46xx_pokeBA0(chip, BA0_SERBSP, 0); */ 3039 3040 /* 3041 * Write the serial port configuration to the part. The master 3042 * enable bit is not set until all other values have been written. 3043 */ 3044 snd_cs46xx_pokeBA0(chip, BA0_SERC1, SERC1_SO1F_AC97 | SERC1_SO1EN); 3045 snd_cs46xx_pokeBA0(chip, BA0_SERC2, SERC2_SI1F_AC97 | SERC1_SO1EN); 3046 snd_cs46xx_pokeBA0(chip, BA0_SERMC1, SERMC1_PTC_AC97 | SERMC1_MSPE); 3047 3048 3049 #ifdef CONFIG_SND_CS46XX_NEW_DSP 3050 snd_cs46xx_pokeBA0(chip, BA0_SERC7, SERC7_ASDI2EN); 3051 snd_cs46xx_pokeBA0(chip, BA0_SERC3, 0); 3052 snd_cs46xx_pokeBA0(chip, BA0_SERC4, 0); 3053 snd_cs46xx_pokeBA0(chip, BA0_SERC5, 0); 3054 snd_cs46xx_pokeBA0(chip, BA0_SERC6, 1); 3055 #endif 3056 3057 mdelay(5); 3058 3059 3060 /* 3061 * Wait for the codec ready signal from the AC97 codec. 3062 */ 3063 timeout = 150; 3064 while (timeout-- > 0) { 3065 /* 3066 * Read the AC97 status register to see if we've seen a CODEC READY 3067 * signal from the AC97 codec. 3068 */ 3069 if (snd_cs46xx_peekBA0(chip, BA0_ACSTS) & ACSTS_CRDY) 3070 goto ok1; 3071 msleep(10); 3072 } 3073 3074 3075 snd_printk(KERN_ERR "create - never read codec ready from AC'97\n"); 3076 snd_printk(KERN_ERR "it is not probably bug, try to use CS4236 driver\n"); 3077 return -EIO; 3078 ok1: 3079 #ifdef CONFIG_SND_CS46XX_NEW_DSP 3080 { 3081 int count; 3082 for (count = 0; count < 150; count++) { 3083 /* First, we want to wait for a short time. */ 3084 udelay(25); 3085 3086 if (snd_cs46xx_peekBA0(chip, BA0_ACSTS2) & ACSTS_CRDY) 3087 break; 3088 } 3089 3090 /* 3091 * Make sure CODEC is READY. 3092 */ 3093 if (!(snd_cs46xx_peekBA0(chip, BA0_ACSTS2) & ACSTS_CRDY)) 3094 snd_printdd("cs46xx: never read card ready from secondary AC'97\n"); 3095 } 3096 #endif 3097 3098 /* 3099 * Assert the vaid frame signal so that we can start sending commands 3100 * to the AC97 codec. 3101 */ 3102 snd_cs46xx_pokeBA0(chip, BA0_ACCTL, ACCTL_VFRM | ACCTL_ESYN | ACCTL_RSTN); 3103 #ifdef CONFIG_SND_CS46XX_NEW_DSP 3104 snd_cs46xx_pokeBA0(chip, BA0_ACCTL2, ACCTL_VFRM | ACCTL_ESYN | ACCTL_RSTN); 3105 #endif 3106 3107 3108 /* 3109 * Wait until we've sampled input slots 3 and 4 as valid, meaning that 3110 * the codec is pumping ADC data across the AC-link. 3111 */ 3112 timeout = 150; 3113 while (timeout-- > 0) { 3114 /* 3115 * Read the input slot valid register and see if input slots 3 and 3116 * 4 are valid yet. 3117 */ 3118 if ((snd_cs46xx_peekBA0(chip, BA0_ACISV) & (ACISV_ISV3 | ACISV_ISV4)) == (ACISV_ISV3 | ACISV_ISV4)) 3119 goto ok2; 3120 msleep(10); 3121 } 3122 3123 #ifndef CONFIG_SND_CS46XX_NEW_DSP 3124 snd_printk(KERN_ERR "create - never read ISV3 & ISV4 from AC'97\n"); 3125 return -EIO; 3126 #else 3127 /* This may happen on a cold boot with a Terratec SiXPack 5.1. 3128 Reloading the driver may help, if there's other soundcards 3129 with the same problem I would like to know. (Benny) */ 3130 3131 snd_printk(KERN_ERR "ERROR: snd-cs46xx: never read ISV3 & ISV4 from AC'97\n"); 3132 snd_printk(KERN_ERR " Try reloading the ALSA driver, if you find something\n"); 3133 snd_printk(KERN_ERR " broken or not working on your soundcard upon\n"); 3134 snd_printk(KERN_ERR " this message please report to alsa-devel@lists.sourceforge.net\n"); 3135 3136 return -EIO; 3137 #endif 3138 ok2: 3139 3140 /* 3141 * Now, assert valid frame and the slot 3 and 4 valid bits. This will 3142 * commense the transfer of digital audio data to the AC97 codec. 3143 */ 3144 3145 snd_cs46xx_pokeBA0(chip, BA0_ACOSV, ACOSV_SLV3 | ACOSV_SLV4); 3146 3147 3148 /* 3149 * Power down the DAC and ADC. We will power them up (if) when we need 3150 * them. 3151 */ 3152 /* snd_cs46xx_pokeBA0(chip, BA0_AC97_POWERDOWN, 0x300); */ 3153 3154 /* 3155 * Turn off the Processor by turning off the software clock enable flag in 3156 * the clock control register. 3157 */ 3158 /* tmp = snd_cs46xx_peekBA0(chip, BA0_CLKCR1) & ~CLKCR1_SWCE; */ 3159 /* snd_cs46xx_pokeBA0(chip, BA0_CLKCR1, tmp); */ 3160 3161 return 0; 3162 } 3163 3164 /* 3165 * start and load DSP 3166 */ 3167 int __devinit snd_cs46xx_start_dsp(cs46xx_t *chip) 3168 { 3169 unsigned int tmp; 3170 /* 3171 * Reset the processor. 3172 */ 3173 snd_cs46xx_reset(chip); 3174 /* 3175 * Download the image to the processor. 3176 */ 3177 #ifdef CONFIG_SND_CS46XX_NEW_DSP 3178 #if 0 3179 if (cs46xx_dsp_load_module(chip, &cwcemb80_module) < 0) { 3180 snd_printk(KERN_ERR "image download error\n"); 3181 return -EIO; 3182 } 3183 #endif 3184 3185 if (cs46xx_dsp_load_module(chip, &cwc4630_module) < 0) { 3186 snd_printk(KERN_ERR "image download error [cwc4630]\n"); 3187 return -EIO; 3188 } 3189 3190 if (cs46xx_dsp_load_module(chip, &cwcasync_module) < 0) { 3191 snd_printk(KERN_ERR "image download error [cwcasync]\n"); 3192 return -EIO; 3193 } 3194 3195 if (cs46xx_dsp_load_module(chip, &cwcsnoop_module) < 0) { 3196 snd_printk(KERN_ERR "image download error [cwcsnoop]\n"); 3197 return -EIO; 3198 } 3199 3200 if (cs46xx_dsp_load_module(chip, &cwcbinhack_module) < 0) { 3201 snd_printk(KERN_ERR "image download error [cwcbinhack]\n"); 3202 return -EIO; 3203 } 3204 3205 if (cs46xx_dsp_load_module(chip, &cwcdma_module) < 0) { 3206 snd_printk(KERN_ERR "image download error [cwcdma]\n"); 3207 return -EIO; 3208 } 3209 3210 if (cs46xx_dsp_scb_and_task_init(chip) < 0) 3211 return -EIO; 3212 #else 3213 /* old image */ 3214 if (snd_cs46xx_download_image(chip) < 0) { 3215 snd_printk(KERN_ERR "image download error\n"); 3216 return -EIO; 3217 } 3218 3219 /* 3220 * Stop playback DMA. 3221 */ 3222 tmp = snd_cs46xx_peek(chip, BA1_PCTL); 3223 chip->play_ctl = tmp & 0xffff0000; 3224 snd_cs46xx_poke(chip, BA1_PCTL, tmp & 0x0000ffff); 3225 #endif 3226 3227 /* 3228 * Stop capture DMA. 3229 */ 3230 tmp = snd_cs46xx_peek(chip, BA1_CCTL); 3231 chip->capt.ctl = tmp & 0x0000ffff; 3232 snd_cs46xx_poke(chip, BA1_CCTL, tmp & 0xffff0000); 3233 3234 mdelay(5); 3235 3236 snd_cs46xx_set_play_sample_rate(chip, 8000); 3237 snd_cs46xx_set_capture_sample_rate(chip, 8000); 3238 3239 snd_cs46xx_proc_start(chip); 3240 3241 /* 3242 * Enable interrupts on the part. 3243 */ 3244 snd_cs46xx_pokeBA0(chip, BA0_HICR, HICR_IEV | HICR_CHGM); 3245 3246 tmp = snd_cs46xx_peek(chip, BA1_PFIE); 3247 tmp &= ~0x0000f03f; 3248 snd_cs46xx_poke(chip, BA1_PFIE, tmp); /* playback interrupt enable */ 3249 3250 tmp = snd_cs46xx_peek(chip, BA1_CIE); 3251 tmp &= ~0x0000003f; 3252 tmp |= 0x00000001; 3253 snd_cs46xx_poke(chip, BA1_CIE, tmp); /* capture interrupt enable */ 3254 3255 #ifndef CONFIG_SND_CS46XX_NEW_DSP 3256 /* set the attenuation to 0dB */ 3257 snd_cs46xx_poke(chip, BA1_PVOL, 0x80008000); 3258 snd_cs46xx_poke(chip, BA1_CVOL, 0x80008000); 3259 #endif 3260 3261 return 0; 3262 } 3263 3264 3265 /* 3266 * AMP control - null AMP 3267 */ 3268 3269 static void amp_none(cs46xx_t *chip, int change) 3270 { 3271 } 3272 3273 #ifdef CONFIG_SND_CS46XX_NEW_DSP 3274 static int voyetra_setup_eapd_slot(cs46xx_t *chip) 3275 { 3276 3277 u32 idx, valid_slots,tmp,powerdown = 0; 3278 u16 modem_power,pin_config,logic_type; 3279 3280 snd_printdd ("cs46xx: cs46xx_setup_eapd_slot()+\n"); 3281 3282 /* 3283 * See if the devices are powered down. If so, we must power them up first 3284 * or they will not respond. 3285 */ 3286 tmp = snd_cs46xx_peekBA0(chip, BA0_CLKCR1); 3287 3288 if (!(tmp & CLKCR1_SWCE)) { 3289 snd_cs46xx_pokeBA0(chip, BA0_CLKCR1, tmp | CLKCR1_SWCE); 3290 powerdown = 1; 3291 } 3292 3293 /* 3294 * Clear PRA. The Bonzo chip will be used for GPIO not for modem 3295 * stuff. 3296 */ 3297 if(chip->nr_ac97_codecs != 2) { 3298 snd_printk (KERN_ERR "cs46xx: cs46xx_setup_eapd_slot() - no secondary codec configured\n"); 3299 return -EINVAL; 3300 } 3301 3302 modem_power = snd_cs46xx_codec_read (chip, 3303 AC97_EXTENDED_MSTATUS, 3304 CS46XX_SECONDARY_CODEC_INDEX); 3305 modem_power &=0xFEFF; 3306 3307 snd_cs46xx_codec_write(chip, 3308 AC97_EXTENDED_MSTATUS, modem_power, 3309 CS46XX_SECONDARY_CODEC_INDEX); 3310 3311 /* 3312 * Set GPIO pin's 7 and 8 so that they are configured for output. 3313 */ 3314 pin_config = snd_cs46xx_codec_read (chip, 3315 AC97_GPIO_CFG, 3316 CS46XX_SECONDARY_CODEC_INDEX); 3317 pin_config &=0x27F; 3318 3319 snd_cs46xx_codec_write(chip, 3320 AC97_GPIO_CFG, pin_config, 3321 CS46XX_SECONDARY_CODEC_INDEX); 3322 3323 /* 3324 * Set GPIO pin's 7 and 8 so that they are compatible with CMOS logic. 3325 */ 3326 3327 logic_type = snd_cs46xx_codec_read(chip, AC97_GPIO_POLARITY, 3328 CS46XX_SECONDARY_CODEC_INDEX); 3329 logic_type &=0x27F; 3330 3331 snd_cs46xx_codec_write (chip, AC97_GPIO_POLARITY, logic_type, 3332 CS46XX_SECONDARY_CODEC_INDEX); 3333 3334 valid_slots = snd_cs46xx_peekBA0(chip, BA0_ACOSV); 3335 valid_slots |= 0x200; 3336 snd_cs46xx_pokeBA0(chip, BA0_ACOSV, valid_slots); 3337 3338 if ( cs46xx_wait_for_fifo(chip,1) ) { 3339 snd_printdd("FIFO is busy\n"); 3340 3341 return -EINVAL; 3342 } 3343 3344 /* 3345 * Fill slots 12 with the correct value for the GPIO pins. 3346 */ 3347 for(idx = 0x90; idx <= 0x9F; idx++) { 3348 /* 3349 * Initialize the fifo so that bits 7 and 8 are on. 3350 * 3351 * Remember that the GPIO pins in bonzo are shifted by 4 bits to 3352 * the left. 0x1800 corresponds to bits 7 and 8. 3353 */ 3354 snd_cs46xx_pokeBA0(chip, BA0_SERBWP, 0x1800); 3355 3356 /* 3357 * Wait for command to complete 3358 */ 3359 if ( cs46xx_wait_for_fifo(chip,200) ) { 3360 snd_printdd("failed waiting for FIFO at addr (%02X)\n",idx); 3361 3362 return -EINVAL; 3363 } 3364 3365 /* 3366 * Write the serial port FIFO index. 3367 */ 3368 snd_cs46xx_pokeBA0(chip, BA0_SERBAD, idx); 3369 3370 /* 3371 * Tell the serial port to load the new value into the FIFO location. 3372 */ 3373 snd_cs46xx_pokeBA0(chip, BA0_SERBCM, SERBCM_WRC); 3374 } 3375 3376 /* wait for last command to complete */ 3377 cs46xx_wait_for_fifo(chip,200); 3378 3379 /* 3380 * Now, if we powered up the devices, then power them back down again. 3381 * This is kinda ugly, but should never happen. 3382 */ 3383 if (powerdown) 3384 snd_cs46xx_pokeBA0(chip, BA0_CLKCR1, tmp); 3385 3386 return 0; 3387 } 3388 #endif 3389 3390 /* 3391 * Crystal EAPD mode 3392 */ 3393 3394 static void amp_voyetra(cs46xx_t *chip, int change) 3395 { 3396 /* Manage the EAPD bit on the Crystal 4297 3397 and the Analog AD1885 */ 3398 3399 #ifdef CONFIG_SND_CS46XX_NEW_DSP 3400 int old = chip->amplifier; 3401 #endif 3402 int oval, val; 3403 3404 chip->amplifier += change; 3405 oval = snd_cs46xx_codec_read(chip, AC97_POWERDOWN, 3406 CS46XX_PRIMARY_CODEC_INDEX); 3407 val = oval; 3408 if (chip->amplifier) { 3409 /* Turn the EAPD amp on */ 3410 val |= 0x8000; 3411 } else { 3412 /* Turn the EAPD amp off */ 3413 val &= ~0x8000; 3414 } 3415 if (val != oval) { 3416 snd_cs46xx_codec_write(chip, AC97_POWERDOWN, val, 3417 CS46XX_PRIMARY_CODEC_INDEX); 3418 if (chip->eapd_switch) 3419 snd_ctl_notify(chip->card, SNDRV_CTL_EVENT_MASK_VALUE, 3420 &chip->eapd_switch->id); 3421 } 3422 3423 #ifdef CONFIG_SND_CS46XX_NEW_DSP 3424 if (chip->amplifier && !old) { 3425 voyetra_setup_eapd_slot(chip); 3426 } 3427 #endif 3428 } 3429 3430 static void hercules_init(cs46xx_t *chip) 3431 { 3432 /* default: AMP off, and SPDIF input optical */ 3433 snd_cs46xx_pokeBA0(chip, BA0_EGPIODR, EGPIODR_GPOE0); 3434 snd_cs46xx_pokeBA0(chip, BA0_EGPIOPTR, EGPIODR_GPOE0); 3435 } 3436 3437 3438 /* 3439 * Game Theatre XP card - EGPIO[2] is used to enable the external amp. 3440 */ 3441 static void amp_hercules(cs46xx_t *chip, int change) 3442 { 3443 int old = chip->amplifier; 3444 int val1 = snd_cs46xx_peekBA0(chip, BA0_EGPIODR); 3445 int val2 = snd_cs46xx_peekBA0(chip, BA0_EGPIOPTR); 3446 3447 chip->amplifier += change; 3448 if (chip->amplifier && !old) { 3449 snd_printdd ("Hercules amplifier ON\n"); 3450 3451 snd_cs46xx_pokeBA0(chip, BA0_EGPIODR, 3452 EGPIODR_GPOE2 | val1); /* enable EGPIO2 output */ 3453 snd_cs46xx_pokeBA0(chip, BA0_EGPIOPTR, 3454 EGPIOPTR_GPPT2 | val2); /* open-drain on output */ 3455 } else if (old && !chip->amplifier) { 3456 snd_printdd ("Hercules amplifier OFF\n"); 3457 snd_cs46xx_pokeBA0(chip, BA0_EGPIODR, val1 & ~EGPIODR_GPOE2); /* disable */ 3458 snd_cs46xx_pokeBA0(chip, BA0_EGPIOPTR, val2 & ~EGPIOPTR_GPPT2); /* disable */ 3459 } 3460 } 3461 3462 static void voyetra_mixer_init (cs46xx_t *chip) 3463 { 3464 snd_printdd ("initializing Voyetra mixer\n"); 3465 3466 /* Enable SPDIF out */ 3467 snd_cs46xx_pokeBA0(chip, BA0_EGPIODR, EGPIODR_GPOE0); 3468 snd_cs46xx_pokeBA0(chip, BA0_EGPIOPTR, EGPIODR_GPOE0); 3469 } 3470 3471 static void hercules_mixer_init (cs46xx_t *chip) 3472 { 3473 #ifdef CONFIG_SND_CS46XX_NEW_DSP 3474 unsigned int idx; 3475 int err; 3476 snd_card_t *card = chip->card; 3477 #endif 3478 3479 /* set EGPIO to default */ 3480 hercules_init(chip); 3481 3482 snd_printdd ("initializing Hercules mixer\n"); 3483 3484 #ifdef CONFIG_SND_CS46XX_NEW_DSP 3485 for (idx = 0 ; idx < ARRAY_SIZE(snd_hercules_controls); idx++) { 3486 snd_kcontrol_t *kctl; 3487 3488 kctl = snd_ctl_new1(&snd_hercules_controls[idx], chip); 3489 if ((err = snd_ctl_add(card, kctl)) < 0) { 3490 printk (KERN_ERR "cs46xx: failed to initialize Hercules mixer (%d)\n",err); 3491 break; 3492 } 3493 } 3494 #endif 3495 } 3496 3497 3498 #if 0 3499 /* 3500 * Untested 3501 */ 3502 3503 static void amp_voyetra_4294(cs46xx_t *chip, int change) 3504 { 3505 chip->amplifier += change; 3506 3507 if (chip->amplifier) { 3508 /* Switch the GPIO pins 7 and 8 to open drain */ 3509 snd_cs46xx_codec_write(chip, 0x4C, 3510 snd_cs46xx_codec_read(chip, 0x4C) & 0xFE7F); 3511 snd_cs46xx_codec_write(chip, 0x4E, 3512 snd_cs46xx_codec_read(chip, 0x4E) | 0x0180); 3513 /* Now wake the AMP (this might be backwards) */ 3514 snd_cs46xx_codec_write(chip, 0x54, 3515 snd_cs46xx_codec_read(chip, 0x54) & ~0x0180); 3516 } else { 3517 snd_cs46xx_codec_write(chip, 0x54, 3518 snd_cs46xx_codec_read(chip, 0x54) | 0x0180); 3519 } 3520 } 3521 #endif 3522 3523 3524 /* 3525 * Handle the CLKRUN on a thinkpad. We must disable CLKRUN support 3526 * whenever we need to beat on the chip. 3527 * 3528 * The original idea and code for this hack comes from David Kaiser at 3529 * Linuxcare. Perhaps one day Crystal will document their chips well 3530 * enough to make them useful. 3531 */ 3532 3533 static void clkrun_hack(cs46xx_t *chip, int change) 3534 { 3535 u16 control, nval; 3536 3537 if (!chip->acpi_port) 3538 return; 3539 3540 chip->amplifier += change; 3541 3542 /* Read ACPI port */ 3543 nval = control = inw(chip->acpi_port + 0x10); 3544 3545 /* Flip CLKRUN off while running */ 3546 if (! chip->amplifier) 3547 nval |= 0x2000; 3548 else 3549 nval &= ~0x2000; 3550 if (nval != control) 3551 outw(nval, chip->acpi_port + 0x10); 3552 } 3553 3554 3555 /* 3556 * detect intel piix4 3557 */ 3558 static void clkrun_init(cs46xx_t *chip) 3559 { 3560 struct pci_dev *pdev; 3561 u8 pp; 3562 3563 chip->acpi_port = 0; 3564 3565 pdev = pci_get_device(PCI_VENDOR_ID_INTEL, 3566 PCI_DEVICE_ID_INTEL_82371AB_3, NULL); 3567 if (pdev == NULL) 3568 return; /* Not a thinkpad thats for sure */ 3569 3570 /* Find the control port */ 3571 pci_read_config_byte(pdev, 0x41, &pp); 3572 chip->acpi_port = pp << 8; 3573 pci_dev_put(pdev); 3574 } 3575 3576 3577 /* 3578 * Card subid table 3579 */ 3580 3581 struct cs_card_type 3582 { 3583 u16 vendor; 3584 u16 id; 3585 char *name; 3586 void (*init)(cs46xx_t *); 3587 void (*amp)(cs46xx_t *, int); 3588 void (*active)(cs46xx_t *, int); 3589 void (*mixer_init)(cs46xx_t *); 3590 }; 3591 3592 static struct cs_card_type __devinitdata cards[] = { 3593 { 3594 .vendor = 0x1489, 3595 .id = 0x7001, 3596 .name = "Genius Soundmaker 128 value", 3597 /* nothing special */ 3598 }, 3599 { 3600 .vendor = 0x5053, 3601 .id = 0x3357, 3602 .name = "Voyetra", 3603 .amp = amp_voyetra, 3604 .mixer_init = voyetra_mixer_init, 3605 }, 3606 { 3607 .vendor = 0x1071, 3608 .id = 0x6003, 3609 .name = "Mitac MI6020/21", 3610 .amp = amp_voyetra, 3611 }, 3612 { 3613 .vendor = 0x14AF, 3614 .id = 0x0050, 3615 .name = "Hercules Game Theatre XP", 3616 .amp = amp_hercules, 3617 .mixer_init = hercules_mixer_init, 3618 }, 3619 { 3620 .vendor = 0x1681, 3621 .id = 0x0050, 3622 .name = "Hercules Game Theatre XP", 3623 .amp = amp_hercules, 3624 .mixer_init = hercules_mixer_init, 3625 }, 3626 { 3627 .vendor = 0x1681, 3628 .id = 0x0051, 3629 .name = "Hercules Game Theatre XP", 3630 .amp = amp_hercules, 3631 .mixer_init = hercules_mixer_init, 3632 3633 }, 3634 { 3635 .vendor = 0x1681, 3636 .id = 0x0052, 3637 .name = "Hercules Game Theatre XP", 3638 .amp = amp_hercules, 3639 .mixer_init = hercules_mixer_init, 3640 }, 3641 { 3642 .vendor = 0x1681, 3643 .id = 0x0053, 3644 .name = "Hercules Game Theatre XP", 3645 .amp = amp_hercules, 3646 .mixer_init = hercules_mixer_init, 3647 }, 3648 { 3649 .vendor = 0x1681, 3650 .id = 0x0054, 3651 .name = "Hercules Game Theatre XP", 3652 .amp = amp_hercules, 3653 .mixer_init = hercules_mixer_init, 3654 }, 3655 /* Teratec */ 3656 { 3657 .vendor = 0x153b, 3658 .id = 0x1136, 3659 .name = "Terratec SiXPack 5.1", 3660 }, 3661 /* Not sure if the 570 needs the clkrun hack */ 3662 { 3663 .vendor = PCI_VENDOR_ID_IBM, 3664 .id = 0x0132, 3665 .name = "Thinkpad 570", 3666 .init = clkrun_init, 3667 .active = clkrun_hack, 3668 }, 3669 { 3670 .vendor = PCI_VENDOR_ID_IBM, 3671 .id = 0x0153, 3672 .name = "Thinkpad 600X/A20/T20", 3673 .init = clkrun_init, 3674 .active = clkrun_hack, 3675 }, 3676 { 3677 .vendor = PCI_VENDOR_ID_IBM, 3678 .id = 0x1010, 3679 .name = "Thinkpad 600E (unsupported)", 3680 }, 3681 {} /* terminator */ 3682 }; 3683 3684 3685 /* 3686 * APM support 3687 */ 3688 #ifdef CONFIG_PM 3689 static int snd_cs46xx_suspend(snd_card_t *card, pm_message_t state) 3690 { 3691 cs46xx_t *chip = card->pm_private_data; 3692 int amp_saved; 3693 3694 snd_pcm_suspend_all(chip->pcm); 3695 // chip->ac97_powerdown = snd_cs46xx_codec_read(chip, AC97_POWER_CONTROL); 3696 // chip->ac97_general_purpose = snd_cs46xx_codec_read(chip, BA0_AC97_GENERAL_PURPOSE); 3697 3698 snd_ac97_suspend(chip->ac97[CS46XX_PRIMARY_CODEC_INDEX]); 3699 if (chip->ac97[CS46XX_SECONDARY_CODEC_INDEX]) 3700 snd_ac97_suspend(chip->ac97[CS46XX_SECONDARY_CODEC_INDEX]); 3701 3702 amp_saved = chip->amplifier; 3703 /* turn off amp */ 3704 chip->amplifier_ctrl(chip, -chip->amplifier); 3705 snd_cs46xx_hw_stop(chip); 3706 /* disable CLKRUN */ 3707 chip->active_ctrl(chip, -chip->amplifier); 3708 chip->amplifier = amp_saved; /* restore the status */ 3709 pci_disable_device(chip->pci); 3710 return 0; 3711 } 3712 3713 static int snd_cs46xx_resume(snd_card_t *card) 3714 { 3715 cs46xx_t *chip = card->pm_private_data; 3716 int amp_saved; 3717 3718 pci_enable_device(chip->pci); 3719 pci_set_master(chip->pci); 3720 amp_saved = chip->amplifier; 3721 chip->amplifier = 0; 3722 chip->active_ctrl(chip, 1); /* force to on */ 3723 3724 snd_cs46xx_chip_init(chip); 3725 3726 #if 0 3727 snd_cs46xx_codec_write(chip, BA0_AC97_GENERAL_PURPOSE, 3728 chip->ac97_general_purpose); 3729 snd_cs46xx_codec_write(chip, AC97_POWER_CONTROL, 3730 chip->ac97_powerdown); 3731 mdelay(10); 3732 snd_cs46xx_codec_write(chip, BA0_AC97_POWERDOWN, 3733 chip->ac97_powerdown); 3734 mdelay(5); 3735 #endif 3736 3737 snd_ac97_resume(chip->ac97[CS46XX_PRIMARY_CODEC_INDEX]); 3738 if (chip->ac97[CS46XX_SECONDARY_CODEC_INDEX]) 3739 snd_ac97_resume(chip->ac97[CS46XX_SECONDARY_CODEC_INDEX]); 3740 3741 if (amp_saved) 3742 chip->amplifier_ctrl(chip, 1); /* turn amp on */ 3743 else 3744 chip->active_ctrl(chip, -1); /* disable CLKRUN */ 3745 chip->amplifier = amp_saved; 3746 return 0; 3747 } 3748 #endif /* CONFIG_PM */ 3749 3750 3751 /* 3752 */ 3753 3754 int __devinit snd_cs46xx_create(snd_card_t * card, 3755 struct pci_dev * pci, 3756 int external_amp, int thinkpad, 3757 cs46xx_t ** rchip) 3758 { 3759 cs46xx_t *chip; 3760 int err, idx; 3761 snd_cs46xx_region_t *region; 3762 struct cs_card_type *cp; 3763 u16 ss_card, ss_vendor; 3764 static snd_device_ops_t ops = { 3765 .dev_free = snd_cs46xx_dev_free, 3766 }; 3767 3768 *rchip = NULL; 3769 3770 /* enable PCI device */ 3771 if ((err = pci_enable_device(pci)) < 0) 3772 return err; 3773 3774 chip = kzalloc(sizeof(*chip), GFP_KERNEL); 3775 if (chip == NULL) { 3776 pci_disable_device(pci); 3777 return -ENOMEM; 3778 } 3779 spin_lock_init(&chip->reg_lock); 3780 #ifdef CONFIG_SND_CS46XX_NEW_DSP 3781 init_MUTEX(&chip->spos_mutex); 3782 #endif 3783 chip->card = card; 3784 chip->pci = pci; 3785 chip->irq = -1; 3786 chip->ba0_addr = pci_resource_start(pci, 0); 3787 chip->ba1_addr = pci_resource_start(pci, 1); 3788 if (chip->ba0_addr == 0 || chip->ba0_addr == (unsigned long)~0 || 3789 chip->ba1_addr == 0 || chip->ba1_addr == (unsigned long)~0) { 3790 snd_printk(KERN_ERR "wrong address(es) - ba0 = 0x%lx, ba1 = 0x%lx\n", chip->ba0_addr, chip->ba1_addr); 3791 snd_cs46xx_free(chip); 3792 return -ENOMEM; 3793 } 3794 3795 region = &chip->region.name.ba0; 3796 strcpy(region->name, "CS46xx_BA0"); 3797 region->base = chip->ba0_addr; 3798 region->size = CS46XX_BA0_SIZE; 3799 3800 region = &chip->region.name.data0; 3801 strcpy(region->name, "CS46xx_BA1_data0"); 3802 region->base = chip->ba1_addr + BA1_SP_DMEM0; 3803 region->size = CS46XX_BA1_DATA0_SIZE; 3804 3805 region = &chip->region.name.data1; 3806 strcpy(region->name, "CS46xx_BA1_data1"); 3807 region->base = chip->ba1_addr + BA1_SP_DMEM1; 3808 region->size = CS46XX_BA1_DATA1_SIZE; 3809 3810 region = &chip->region.name.pmem; 3811 strcpy(region->name, "CS46xx_BA1_pmem"); 3812 region->base = chip->ba1_addr + BA1_SP_PMEM; 3813 region->size = CS46XX_BA1_PRG_SIZE; 3814 3815 region = &chip->region.name.reg; 3816 strcpy(region->name, "CS46xx_BA1_reg"); 3817 region->base = chip->ba1_addr + BA1_SP_REG; 3818 region->size = CS46XX_BA1_REG_SIZE; 3819 3820 /* set up amp and clkrun hack */ 3821 pci_read_config_word(pci, PCI_SUBSYSTEM_VENDOR_ID, &ss_vendor); 3822 pci_read_config_word(pci, PCI_SUBSYSTEM_ID, &ss_card); 3823 3824 for (cp = &cards[0]; cp->name; cp++) { 3825 if (cp->vendor == ss_vendor && cp->id == ss_card) { 3826 snd_printdd ("hack for %s enabled\n", cp->name); 3827 3828 chip->amplifier_ctrl = cp->amp; 3829 chip->active_ctrl = cp->active; 3830 chip->mixer_init = cp->mixer_init; 3831 3832 if (cp->init) 3833 cp->init(chip); 3834 break; 3835 } 3836 } 3837 3838 if (external_amp) { 3839 snd_printk(KERN_INFO "Crystal EAPD support forced on.\n"); 3840 chip->amplifier_ctrl = amp_voyetra; 3841 } 3842 3843 if (thinkpad) { 3844 snd_printk(KERN_INFO "Activating CLKRUN hack for Thinkpad.\n"); 3845 chip->active_ctrl = clkrun_hack; 3846 clkrun_init(chip); 3847 } 3848 3849 if (chip->amplifier_ctrl == NULL) 3850 chip->amplifier_ctrl = amp_none; 3851 if (chip->active_ctrl == NULL) 3852 chip->active_ctrl = amp_none; 3853 3854 chip->active_ctrl(chip, 1); /* enable CLKRUN */ 3855 3856 pci_set_master(pci); 3857 3858 for (idx = 0; idx < 5; idx++) { 3859 region = &chip->region.idx[idx]; 3860 if ((region->resource = request_mem_region(region->base, region->size, region->name)) == NULL) { 3861 snd_printk(KERN_ERR "unable to request memory region 0x%lx-0x%lx\n", region->base, region->base + region->size - 1); 3862 snd_cs46xx_free(chip); 3863 return -EBUSY; 3864 } 3865 region->remap_addr = ioremap_nocache(region->base, region->size); 3866 if (region->remap_addr == NULL) { 3867 snd_printk(KERN_ERR "%s ioremap problem\n", region->name); 3868 snd_cs46xx_free(chip); 3869 return -ENOMEM; 3870 } 3871 } 3872 3873 if (request_irq(pci->irq, snd_cs46xx_interrupt, SA_INTERRUPT|SA_SHIRQ, "CS46XX", (void *) chip)) { 3874 snd_printk(KERN_ERR "unable to grab IRQ %d\n", pci->irq); 3875 snd_cs46xx_free(chip); 3876 return -EBUSY; 3877 } 3878 chip->irq = pci->irq; 3879 3880 #ifdef CONFIG_SND_CS46XX_NEW_DSP 3881 chip->dsp_spos_instance = cs46xx_dsp_spos_create(chip); 3882 if (chip->dsp_spos_instance == NULL) { 3883 snd_cs46xx_free(chip); 3884 return -ENOMEM; 3885 } 3886 #endif 3887 3888 err = snd_cs46xx_chip_init(chip); 3889 if (err < 0) { 3890 snd_cs46xx_free(chip); 3891 return err; 3892 } 3893 3894 if ((err = snd_device_new(card, SNDRV_DEV_LOWLEVEL, chip, &ops)) < 0) { 3895 snd_cs46xx_free(chip); 3896 return err; 3897 } 3898 3899 snd_cs46xx_proc_init(card, chip); 3900 3901 snd_card_set_pm_callback(card, snd_cs46xx_suspend, snd_cs46xx_resume, chip); 3902 3903 chip->active_ctrl(chip, -1); /* disable CLKRUN */ 3904 3905 snd_card_set_dev(card, &pci->dev); 3906 3907 *rchip = chip; 3908 return 0; 3909 } 3910