49 #include <linux/pci.h>
53 #include <linux/slab.h>
54 #include <linux/gameport.h>
56 #include <linux/export.h>
73 #ifdef CONFIG_SND_CS46XX_NEW_DSP
74 static struct snd_pcm_ops snd_cs46xx_playback_rear_ops;
75 static struct snd_pcm_ops snd_cs46xx_playback_indirect_rear_ops;
76 static struct snd_pcm_ops snd_cs46xx_playback_clfe_ops;
77 static struct snd_pcm_ops snd_cs46xx_playback_indirect_clfe_ops;
78 static struct snd_pcm_ops snd_cs46xx_playback_iec958_ops;
79 static struct snd_pcm_ops snd_cs46xx_playback_indirect_iec958_ops;
83 static struct snd_pcm_ops snd_cs46xx_playback_indirect_ops;
85 static struct snd_pcm_ops snd_cs46xx_capture_indirect_ops;
87 static unsigned short snd_cs46xx_codec_read(
struct snd_cs46xx *
chip,
113 snd_cs46xx_peekBA0(chip,
BA0_ACSDA + offset);
115 tmp = snd_cs46xx_peekBA0(chip,
BA0_ACCTL);
120 tmp = snd_cs46xx_peekBA0(chip,
BA0_ACCTL + offset);
138 snd_cs46xx_pokeBA0(chip,
BA0_ACCAD, reg);
156 for (count = 0; count < 1000; count++) {
177 for (count = 0; count < 100; count++) {
188 snd_printk(
KERN_ERR "AC'97 read problem (ACSTS_VSTS), codec_index %d, reg = 0x%x\n", codec_index, reg);
204 result = snd_cs46xx_peekBA0(chip,
BA0_ACSDA + offset);
210 static unsigned short snd_cs46xx_ac97_read(
struct snd_ac97 * ac97,
215 int codec_index = ac97->
num;
221 val = snd_cs46xx_codec_read(chip, reg, codec_index);
227 static void snd_cs46xx_codec_write(
struct snd_cs46xx *chip,
260 snd_cs46xx_pokeBA0(chip,
BA0_ACCAD , reg);
261 snd_cs46xx_pokeBA0(chip,
BA0_ACCDA , val);
265 snd_cs46xx_pokeBA0(chip,
BA0_ACCTL, ACCTL_VFRM |
274 for (count = 0; count < 4000; count++) {
287 snd_printk(
KERN_ERR "AC'97 write problem, codec_index = %d, reg = 0x%x, val = 0x%x\n", codec_index, reg, val);
292 static void snd_cs46xx_ac97_write(
struct snd_ac97 *ac97,
297 int codec_index = ac97->
num;
303 snd_cs46xx_codec_write(chip, reg, val, codec_index);
313 unsigned long offset,
317 unsigned int bank = offset >> 16;
318 offset = offset & 0xffff;
333 #ifdef CONFIG_SND_CS46XX_NEW_DSP
342 unsigned long offset,
346 unsigned int bank = offset >> 16;
347 offset = offset & 0xffff;
369 unsigned long offset = 0;
373 &BA1Struct.map[offset],
374 BA1Struct.memory[idx].offset,
375 BA1Struct.memory[idx].size)) < 0)
377 offset += BA1Struct.memory[
idx].size >> 2;
387 static void snd_cs46xx_reset(
struct snd_cs46xx *chip)
404 for (idx = 0; idx < 8; idx++) {
406 snd_cs46xx_poke(chip,
BA1_TWPR, 0xFFFF);
413 snd_cs46xx_poke(chip,
BA1_FRMT, 0xadf);
416 static int cs46xx_wait_for_fifo(
struct snd_cs46xx * chip,
int retry_timeout)
422 for(i = 0; i < 50; i++){
423 status = snd_cs46xx_peekBA0(chip,
BA0_SERBST);
433 "FIFO command to complete\n");
440 static void snd_cs46xx_clear_serial_FIFOs(
struct snd_cs46xx *chip)
442 int idx, powerdown = 0;
451 snd_cs46xx_pokeBA0(chip,
BA0_CLKCR1, tmp | CLKCR1_SWCE);
465 for (idx = 0; idx < 0xFF; idx++) {
469 if (cs46xx_wait_for_fifo(chip,1)) {
470 snd_printdd (
"failed waiting for FIFO at addr (%02X)\n",idx);
494 static void snd_cs46xx_proc_start(
struct snd_cs46xx *chip)
501 snd_cs46xx_poke(chip,
BA1_FRMT, 0xadf);
511 for (cnt = 0; cnt < 25; cnt++) {
521 static void snd_cs46xx_proc_stop(
struct snd_cs46xx *chip)
534 #define GOF_PER_SEC 200
536 static void snd_cs46xx_set_play_sample_rate(
struct snd_cs46xx *chip,
unsigned int rate)
539 unsigned int tmp1, tmp2;
540 unsigned int phiIncr;
541 unsigned int correctionPerGOF, correctionPerSec;
561 phiIncr = tmp1 / 48000;
562 tmp1 -= phiIncr * 48000;
567 tmp1 -= tmp2 * 48000;
570 correctionPerSec =
tmp1;
577 ((correctionPerSec << 16) & 0xFFFF0000) | (correctionPerGOF & 0xFFFF));
578 snd_cs46xx_poke(chip,
BA1_PPI, phiIncr);
579 spin_unlock_irqrestore(&chip->
reg_lock, flags);
582 static void snd_cs46xx_set_capture_sample_rate(
struct snd_cs46xx *chip,
unsigned int rate)
585 unsigned int phiIncr, coeffIncr,
tmp1, tmp2;
586 unsigned int correctionPerGOF, correctionPerSec, initialDelay;
587 unsigned int frameGroupLength,
cnt;
593 if ((rate * 9) < 48000)
626 coeffIncr = tmp1 / 48000;
627 tmp1 -= coeffIncr * 48000;
630 coeffIncr += tmp1 / 48000;
631 coeffIncr ^= 0xFFFFFFFF;
634 phiIncr = tmp1 /
rate;
635 tmp1 -= phiIncr *
rate;
643 correctionPerSec =
tmp1;
644 initialDelay = ((48000 * 24) + rate - 1) /
rate;
651 ((correctionPerSec << 16) & 0xFFFF0000) | (correctionPerGOF & 0xFFFF));
652 snd_cs46xx_poke(chip,
BA1_CCI, coeffIncr);
653 snd_cs46xx_poke(chip,
BA1_CD,
655 snd_cs46xx_poke(chip,
BA1_CPI, phiIncr);
656 spin_unlock_irqrestore(&chip->
reg_lock, flags);
663 frameGroupLength = 1;
664 for (cnt = 2; cnt <= 64; cnt *= 2) {
665 if (((rate / cnt) * cnt) != rate)
666 frameGroupLength *= 2;
668 if (((rate / 3) * 3) != rate) {
669 frameGroupLength *= 3;
671 for (cnt = 5; cnt <= 125; cnt *= 5) {
672 if (((rate / cnt) * cnt) != rate)
673 frameGroupLength *= 5;
680 snd_cs46xx_poke(chip,
BA1_CFG1, frameGroupLength);
681 snd_cs46xx_poke(chip,
BA1_CFG2, (0x00800000 | frameGroupLength));
682 snd_cs46xx_poke(chip,
BA1_CCST, 0x0000FFFF);
683 snd_cs46xx_poke(chip,
BA1_CSPB, ((65536 * rate) / 24000));
684 snd_cs46xx_poke(chip, (
BA1_CSPB + 4), 0x0000FFFF);
685 spin_unlock_irqrestore(&chip->
reg_lock, flags);
704 snd_pcm_indirect_playback_transfer(substream, &cpcm->
pcm_rec, snd_cs46xx_pb_trans_copy);
720 snd_pcm_indirect_capture_transfer(substream, &chip->
capt.pcm_rec, snd_cs46xx_cp_trans_copy);
733 #ifdef CONFIG_SND_CS46XX_NEW_DSP
734 ptr = snd_cs46xx_peek(chip, (cpcm->
pcm_channel->pcm_reader_scb->address + 2) << 2);
736 ptr = snd_cs46xx_peek(chip,
BA1_PBA);
739 return ptr >> cpcm->
shift;
748 #ifdef CONFIG_SND_CS46XX_NEW_DSP
751 ptr = snd_cs46xx_peek(chip, (cpcm->
pcm_channel->pcm_reader_scb->address + 2) << 2);
753 ptr = snd_cs46xx_peek(chip,
BA1_PBA);
756 return snd_pcm_indirect_playback_pointer(substream, &cpcm->
pcm_rec, ptr);
762 size_t ptr = snd_cs46xx_peek(chip,
BA1_CBA) - chip->
capt.hw_buf.addr;
763 return ptr >> chip->
capt.shift;
769 size_t ptr = snd_cs46xx_peek(chip,
BA1_CBA) - chip->
capt.hw_buf.addr;
770 return snd_pcm_indirect_capture_pointer(substream, &chip->
capt.pcm_rec, ptr);
780 #ifdef CONFIG_SND_CS46XX_NEW_DSP
789 #ifdef CONFIG_SND_CS46XX_NEW_DSP
791 snd_cs46xx_poke(chip, (cpcm->
pcm_channel->pcm_reader_scb->address +
792 SCBVolumeCtrl) << 2, 0x80008000);
798 snd_cs46xx_playback_transfer(substream);
802 snd_cs46xx_playback_transfer(substream);
804 tmp = snd_cs46xx_peek(chip,
BA1_PCTL);
813 #ifdef CONFIG_SND_CS46XX_NEW_DSP
815 snd_cs46xx_poke(chip, (cpcm->
pcm_channel->pcm_reader_scb->address +
816 SCBVolumeCtrl) << 2, 0xffffffff);
823 tmp = snd_cs46xx_peek(chip,
BA1_PCTL);
825 snd_cs46xx_poke(chip,
BA1_PCTL, tmp);
849 tmp = snd_cs46xx_peek(chip,
BA1_CCTL);
855 tmp = snd_cs46xx_peek(chip,
BA1_CCTL);
857 snd_cs46xx_poke(chip,
BA1_CCTL, tmp);
868 #ifdef CONFIG_SND_CS46XX_NEW_DSP
884 if ((
int)cpcm->
pcm_channel->sample_rate != sample_rate) {
910 #ifdef CONFIG_SND_CS46XX_NEW_DSP
913 int period_size = params_period_bytes(hw_params);
917 #ifdef CONFIG_SND_CS46XX_NEW_DSP
923 if (_cs46xx_adjust_sample_rate (chip,cpcm,sample_rate)) {
940 snd_printdd (
"period_size (%d), periods (%d) buffer_size(%d)\n",
953 #ifdef CONFIG_SND_CS46XX_NEW_DSP
955 substream->
ops = &snd_cs46xx_playback_ops;
957 substream->
ops = &snd_cs46xx_playback_rear_ops;
959 substream->
ops = &snd_cs46xx_playback_clfe_ops;
961 substream->
ops = &snd_cs46xx_playback_iec958_ops;
966 substream->
ops = &snd_cs46xx_playback_ops;
976 #ifdef CONFIG_SND_CS46XX_NEW_DSP
982 #ifdef CONFIG_SND_CS46XX_NEW_DSP
984 substream->
ops = &snd_cs46xx_playback_indirect_ops;
986 substream->
ops = &snd_cs46xx_playback_indirect_rear_ops;
988 substream->
ops = &snd_cs46xx_playback_indirect_clfe_ops;
990 substream->
ops = &snd_cs46xx_playback_indirect_iec958_ops;
995 substream->
ops = &snd_cs46xx_playback_indirect_ops;
1000 #ifdef CONFIG_SND_CS46XX_NEW_DSP
1017 if (!cpcm)
return -
ENXIO;
1039 #ifdef CONFIG_SND_CS46XX_NEW_DSP
1043 pfie = snd_cs46xx_peek(chip, (cpcm->
pcm_channel->pcm_reader_scb->address + 1) << 2 );
1044 pfie &= ~0x0000f03f;
1047 pfie = snd_cs46xx_peek(chip,
BA1_PFIE);
1048 pfie &= ~0x0000f03f;
1074 cpcm->
pcm_rec.sw_buffer_size = snd_pcm_lib_buffer_bytes(substream);
1077 #ifdef CONFIG_SND_CS46XX_NEW_DSP
1079 tmp = snd_cs46xx_peek(chip, (cpcm->
pcm_channel->pcm_reader_scb->address) << 2);
1081 tmp |= (4 << cpcm->
shift) - 1;
1083 snd_cs46xx_poke(chip, (cpcm->
pcm_channel->pcm_reader_scb->address) << 2, tmp);
1086 snd_cs46xx_poke(chip, (cpcm->
pcm_channel->pcm_reader_scb->address + 1) << 2, pfie | cpcm->
pcm_channel->pcm_slot);
1089 tmp = snd_cs46xx_peek(chip,
BA1_PDTC);
1091 tmp |= (4 << cpcm->
shift) - 1;
1092 snd_cs46xx_poke(chip,
BA1_PDTC, tmp);
1093 snd_cs46xx_poke(chip,
BA1_PFIE, pfie);
1094 snd_cs46xx_set_play_sample_rate(chip, runtime->
rate);
1107 #ifdef CONFIG_SND_CS46XX_NEW_DSP
1116 substream->
ops = &snd_cs46xx_capture_ops;
1125 substream->
ops = &snd_cs46xx_capture_indirect_ops;
1150 snd_cs46xx_poke(chip,
BA1_CBA, chip->
capt.hw_buf.addr);
1151 chip->
capt.shift = 2;
1153 chip->
capt.pcm_rec.sw_buffer_size = snd_pcm_lib_buffer_bytes(substream);
1155 snd_cs46xx_set_capture_sample_rate(chip, runtime->
rate);
1164 #ifdef CONFIG_SND_CS46XX_NEW_DSP
1174 status1 = snd_cs46xx_peekBA0(chip,
BA0_HISR);
1175 if ((status1 & 0x7fffffff) == 0) {
1180 #ifdef CONFIG_SND_CS46XX_NEW_DSP
1181 status2 = snd_cs46xx_peekBA0(chip,
BA0_HSR0);
1185 if ( status1 & (1 << i) ) {
1187 if (chip->
capt.substream)
1199 if ( status2 & (1 << (i - 16))) {
1217 if (chip->
capt.substream)
1227 c = snd_cs46xx_peekBA0(chip,
BA0_MIDRP);
1266 .buffer_bytes_max = (256 * 1024),
1290 .periods_max = 1024,
1294 #ifdef CONFIG_SND_CS46XX_NEW_DSP
1296 static unsigned int period_sizes[] = { 32, 64, 128, 256, 512, 1024, 2048 };
1300 .list = period_sizes,
1306 static void snd_cs46xx_pcm_free_substream(
struct snd_pcm_runtime *runtime)
1311 static int _cs46xx_playback_open_channel (
struct snd_pcm_substream *substream,
int pcm_channel_id)
1326 runtime->
hw = snd_cs46xx_playback;
1331 #ifdef CONFIG_SND_CS46XX_NEW_DSP
1339 &hw_constraints_period_sizes);
1359 #ifdef CONFIG_SND_CS46XX_NEW_DSP
1389 static int snd_cs46xx_playback_close_iec958(
struct snd_pcm_substream *substream)
1396 err = snd_cs46xx_playback_close(substream);
1414 substream->
runtime->hw = snd_cs46xx_capture;
1421 #ifdef CONFIG_SND_CS46XX_NEW_DSP
1424 &hw_constraints_period_sizes);
1438 if (!cpcm)
return -
ENXIO;
1440 #ifdef CONFIG_SND_CS46XX_NEW_DSP
1469 #ifdef CONFIG_SND_CS46XX_NEW_DSP
1470 static struct snd_pcm_ops snd_cs46xx_playback_rear_ops = {
1471 .
open = snd_cs46xx_playback_open_rear,
1472 .close = snd_cs46xx_playback_close,
1474 .hw_params = snd_cs46xx_playback_hw_params,
1475 .hw_free = snd_cs46xx_playback_hw_free,
1476 .prepare = snd_cs46xx_playback_prepare,
1477 .trigger = snd_cs46xx_playback_trigger,
1478 .pointer = snd_cs46xx_playback_direct_pointer,
1481 static struct snd_pcm_ops snd_cs46xx_playback_indirect_rear_ops = {
1482 .
open = snd_cs46xx_playback_open_rear,
1483 .close = snd_cs46xx_playback_close,
1485 .hw_params = snd_cs46xx_playback_hw_params,
1486 .hw_free = snd_cs46xx_playback_hw_free,
1487 .prepare = snd_cs46xx_playback_prepare,
1488 .trigger = snd_cs46xx_playback_trigger,
1489 .pointer = snd_cs46xx_playback_indirect_pointer,
1490 .ack = snd_cs46xx_playback_transfer,
1493 static struct snd_pcm_ops snd_cs46xx_playback_clfe_ops = {
1494 .
open = snd_cs46xx_playback_open_clfe,
1495 .close = snd_cs46xx_playback_close,
1497 .hw_params = snd_cs46xx_playback_hw_params,
1498 .hw_free = snd_cs46xx_playback_hw_free,
1499 .prepare = snd_cs46xx_playback_prepare,
1500 .trigger = snd_cs46xx_playback_trigger,
1501 .pointer = snd_cs46xx_playback_direct_pointer,
1504 static struct snd_pcm_ops snd_cs46xx_playback_indirect_clfe_ops = {
1505 .
open = snd_cs46xx_playback_open_clfe,
1506 .close = snd_cs46xx_playback_close,
1508 .hw_params = snd_cs46xx_playback_hw_params,
1509 .hw_free = snd_cs46xx_playback_hw_free,
1510 .prepare = snd_cs46xx_playback_prepare,
1511 .trigger = snd_cs46xx_playback_trigger,
1512 .pointer = snd_cs46xx_playback_indirect_pointer,
1513 .ack = snd_cs46xx_playback_transfer,
1516 static struct snd_pcm_ops snd_cs46xx_playback_iec958_ops = {
1517 .
open = snd_cs46xx_playback_open_iec958,
1518 .close = snd_cs46xx_playback_close_iec958,
1520 .hw_params = snd_cs46xx_playback_hw_params,
1521 .hw_free = snd_cs46xx_playback_hw_free,
1522 .prepare = snd_cs46xx_playback_prepare,
1523 .trigger = snd_cs46xx_playback_trigger,
1524 .pointer = snd_cs46xx_playback_direct_pointer,
1527 static struct snd_pcm_ops snd_cs46xx_playback_indirect_iec958_ops = {
1528 .
open = snd_cs46xx_playback_open_iec958,
1529 .close = snd_cs46xx_playback_close_iec958,
1531 .hw_params = snd_cs46xx_playback_hw_params,
1532 .hw_free = snd_cs46xx_playback_hw_free,
1533 .prepare = snd_cs46xx_playback_prepare,
1534 .trigger = snd_cs46xx_playback_trigger,
1535 .pointer = snd_cs46xx_playback_indirect_pointer,
1536 .ack = snd_cs46xx_playback_transfer,
1541 static struct snd_pcm_ops snd_cs46xx_playback_ops = {
1542 .open = snd_cs46xx_playback_open,
1543 .close = snd_cs46xx_playback_close,
1545 .hw_params = snd_cs46xx_playback_hw_params,
1546 .hw_free = snd_cs46xx_playback_hw_free,
1547 .prepare = snd_cs46xx_playback_prepare,
1548 .trigger = snd_cs46xx_playback_trigger,
1549 .pointer = snd_cs46xx_playback_direct_pointer,
1552 static struct snd_pcm_ops snd_cs46xx_playback_indirect_ops = {
1553 .open = snd_cs46xx_playback_open,
1554 .close = snd_cs46xx_playback_close,
1556 .hw_params = snd_cs46xx_playback_hw_params,
1557 .hw_free = snd_cs46xx_playback_hw_free,
1558 .prepare = snd_cs46xx_playback_prepare,
1559 .trigger = snd_cs46xx_playback_trigger,
1560 .pointer = snd_cs46xx_playback_indirect_pointer,
1561 .ack = snd_cs46xx_playback_transfer,
1564 static struct snd_pcm_ops snd_cs46xx_capture_ops = {
1565 .open = snd_cs46xx_capture_open,
1566 .close = snd_cs46xx_capture_close,
1568 .hw_params = snd_cs46xx_capture_hw_params,
1569 .hw_free = snd_cs46xx_capture_hw_free,
1570 .prepare = snd_cs46xx_capture_prepare,
1571 .trigger = snd_cs46xx_capture_trigger,
1572 .pointer = snd_cs46xx_capture_direct_pointer,
1575 static struct snd_pcm_ops snd_cs46xx_capture_indirect_ops = {
1576 .open = snd_cs46xx_capture_open,
1577 .close = snd_cs46xx_capture_close,
1579 .hw_params = snd_cs46xx_capture_hw_params,
1580 .hw_free = snd_cs46xx_capture_hw_free,
1581 .prepare = snd_cs46xx_capture_prepare,
1582 .trigger = snd_cs46xx_capture_trigger,
1583 .pointer = snd_cs46xx_capture_indirect_pointer,
1584 .ack = snd_cs46xx_capture_transfer,
1587 #ifdef CONFIG_SND_CS46XX_NEW_DSP
1588 #define MAX_PLAYBACK_CHANNELS (DSP_MAX_PCM_CHANNELS - 1)
1590 #define MAX_PLAYBACK_CHANNELS 1
1623 #ifdef CONFIG_SND_CS46XX_NEW_DSP
1642 chip->pcm_rear = pcm;
1671 chip->pcm_center_lfe = pcm;
1690 if ((err =
snd_pcm_new(chip->
card,
"CS46xx - IEC958", device, 1, 0, &pcm)) < 0)
1700 chip->pcm_rear = pcm;
1722 static void snd_cs46xx_mixer_free_ac97(
struct snd_ac97 *ac97)
1738 static int snd_cs46xx_vol_info(
struct snd_kcontrol *kcontrol,
1752 unsigned int val = snd_cs46xx_peek(chip, reg);
1753 ucontrol->
value.integer.value[0] = 0xffff - (val >> 16);
1754 ucontrol->
value.integer.value[1] = 0xffff - (val & 0xffff);
1762 unsigned int val = ((0xffff - ucontrol->
value.integer.value[0]) << 16 |
1763 (0xffff - ucontrol->
value.integer.value[1]));
1764 unsigned int old = snd_cs46xx_peek(chip, reg);
1765 int change = (old !=
val);
1768 snd_cs46xx_poke(chip, reg, val);
1774 #ifdef CONFIG_SND_CS46XX_NEW_DSP
1780 ucontrol->
value.integer.value[0] = chip->dsp_spos_instance->dac_volume_left;
1781 ucontrol->
value.integer.value[1] = chip->dsp_spos_instance->dac_volume_right;
1791 if (chip->dsp_spos_instance->dac_volume_right != ucontrol->
value.integer.value[0] ||
1792 chip->dsp_spos_instance->dac_volume_left != ucontrol->
value.integer.value[1]) {
1794 ucontrol->
value.integer.value[0],
1795 ucontrol->
value.integer.value[1]);
1807 ucontrol->
value.integer.value[0] = chip->dsp_spos_instance->spdif_input_volume_left;
1808 ucontrol->
value.integer.value[1] = chip->dsp_spos_instance->spdif_input_volume_right;
1817 if (chip->dsp_spos_instance->spdif_input_volume_left != ucontrol->
value.integer.value[0] ||
1818 chip->dsp_spos_instance->spdif_input_volume_right!= ucontrol->
value.integer.value[1]) {
1820 ucontrol->
value.integer.value[0],
1821 ucontrol->
value.integer.value[1]);
1829 #define snd_mixer_boolean_info snd_ctl_boolean_mono_info
1831 static int snd_cs46xx_iec958_get(
struct snd_kcontrol *kcontrol,
1840 ucontrol->
value.integer.value[0] = chip->dsp_spos_instance->spdif_status_in;
1845 static int snd_cs46xx_iec958_put(
struct snd_kcontrol *kcontrol,
1855 if (ucontrol->
value.integer.value[0] && !change)
1857 else if (change && !ucontrol->
value.integer.value[0])
1864 change = chip->dsp_spos_instance->spdif_status_in;
1865 if (ucontrol->
value.integer.value[0] && !change) {
1869 else if (change && !ucontrol->
value.integer.value[0])
1872 res = (change != chip->dsp_spos_instance->spdif_status_in);
1882 static int snd_cs46xx_adc_capture_get(
struct snd_kcontrol *kcontrol,
1889 ucontrol->
value.integer.value[0] = 1;
1891 ucontrol->
value.integer.value[0] = 0;
1896 static int snd_cs46xx_adc_capture_put(
struct snd_kcontrol *kcontrol,
1906 }
else if (!ucontrol->
value.integer.value[0] && ins->
adc_input) {
1913 static int snd_cs46xx_pcm_capture_get(
struct snd_kcontrol *kcontrol,
1920 ucontrol->
value.integer.value[0] = 1;
1922 ucontrol->
value.integer.value[0] = 0;
1928 static int snd_cs46xx_pcm_capture_put(
struct snd_kcontrol *kcontrol,
1938 }
else if (!ucontrol->
value.integer.value[0] && ins->
pcm_input) {
1946 static int snd_herc_spdif_select_get(
struct snd_kcontrol *kcontrol,
1954 ucontrol->
value.integer.value[0] = 1;
1956 ucontrol->
value.integer.value[0] = 0;
1964 static int snd_herc_spdif_select_put(
struct snd_kcontrol *kcontrol,
1971 if (ucontrol->
value.integer.value[0]) {
1985 return (val1 != (
int)snd_cs46xx_peekBA0(chip,
BA0_EGPIODR));
1996 static int snd_cs46xx_spdif_default_get(
struct snd_kcontrol *kcontrol,
2005 ucontrol->
value.iec958.status[2] = 0;
2012 static int snd_cs46xx_spdif_default_put(
struct snd_kcontrol *kcontrol,
2021 val = ((
unsigned int)_wrap_all_bits(ucontrol->
value.iec958.status[0]) << 24) |
2022 ((
unsigned int)_wrap_all_bits(ucontrol->
value.iec958.status[2]) << 16) |
2023 ((
unsigned int)_wrap_all_bits(ucontrol->
value.iec958.status[3])) |
2025 (1 << 13) | (1 << 12);
2039 static int snd_cs46xx_spdif_mask_get(
struct snd_kcontrol *kcontrol,
2042 ucontrol->
value.iec958.status[0] = 0xff;
2043 ucontrol->
value.iec958.status[1] = 0xff;
2044 ucontrol->
value.iec958.status[2] = 0x00;
2045 ucontrol->
value.iec958.status[3] = 0xff;
2049 static int snd_cs46xx_spdif_stream_get(
struct snd_kcontrol *kcontrol,
2058 ucontrol->
value.iec958.status[2] = 0;
2065 static int snd_cs46xx_spdif_stream_put(
struct snd_kcontrol *kcontrol,
2074 val = ((
unsigned int)_wrap_all_bits(ucontrol->
value.iec958.status[0]) << 24) |
2075 ((
unsigned int)_wrap_all_bits(ucontrol->
value.iec958.status[1]) << 16) |
2076 ((
unsigned int)_wrap_all_bits(ucontrol->
value.iec958.status[3])) |
2078 (1 << 13) | (1 << 12);
2098 .name =
"DAC Volume",
2099 .info = snd_cs46xx_vol_info,
2100 #ifndef CONFIG_SND_CS46XX_NEW_DSP
2101 .get = snd_cs46xx_vol_get,
2102 .put = snd_cs46xx_vol_put,
2105 .get = snd_cs46xx_vol_dac_get,
2106 .put = snd_cs46xx_vol_dac_put,
2112 .name =
"ADC Volume",
2113 .info = snd_cs46xx_vol_info,
2114 .get = snd_cs46xx_vol_get,
2115 .put = snd_cs46xx_vol_put,
2116 #ifndef CONFIG_SND_CS46XX_NEW_DSP
2119 .private_value = (VARIDECIMATE_SCB_ADDR + 0xE) << 2,
2122 #ifdef CONFIG_SND_CS46XX_NEW_DSP
2125 .name =
"ADC Capture Switch",
2126 .info = snd_mixer_boolean_info,
2127 .get = snd_cs46xx_adc_capture_get,
2128 .put = snd_cs46xx_adc_capture_put
2132 .name =
"DAC Capture Switch",
2133 .info = snd_mixer_boolean_info,
2134 .get = snd_cs46xx_pcm_capture_get,
2135 .put = snd_cs46xx_pcm_capture_put
2140 .info = snd_mixer_boolean_info,
2141 .get = snd_cs46xx_iec958_get,
2142 .put = snd_cs46xx_iec958_put,
2148 .info = snd_mixer_boolean_info,
2149 .get = snd_cs46xx_iec958_get,
2150 .put = snd_cs46xx_iec958_put,
2158 .info = snd_cs46xx_vol_info,
2159 .get = snd_cs46xx_vol_iec958_get,
2160 .put = snd_cs46xx_vol_iec958_put,
2161 .private_value = (ASYNCRX_SCB_ADDR + 0xE) << 2,
2167 .info = snd_cs46xx_spdif_info,
2168 .get = snd_cs46xx_spdif_default_get,
2169 .put = snd_cs46xx_spdif_default_put,
2174 .info = snd_cs46xx_spdif_info,
2175 .get = snd_cs46xx_spdif_mask_get,
2181 .info = snd_cs46xx_spdif_info,
2182 .get = snd_cs46xx_spdif_stream_get,
2183 .put = snd_cs46xx_spdif_stream_put
2189 #ifdef CONFIG_SND_CS46XX_NEW_DSP
2191 static int snd_cs46xx_front_dup_get(
struct snd_kcontrol *kcontrol,
2197 ucontrol->
value.integer.value[0] = (val & 0x200) ? 0 : 1;
2201 static int snd_cs46xx_front_dup_put(
struct snd_kcontrol *kcontrol,
2207 ucontrol->
value.integer.value[0] ? 0 : 0x200);
2212 .name =
"Duplicate Front",
2213 .info = snd_mixer_boolean_info,
2214 .get = snd_cs46xx_front_dup_get,
2215 .put = snd_cs46xx_front_dup_put,
2219 #ifdef CONFIG_SND_CS46XX_NEW_DSP
2224 .name =
"Optical/Coaxial SPDIF Input Switch",
2225 .info = snd_mixer_boolean_info,
2226 .get = snd_herc_spdif_select_get,
2227 .put = snd_herc_spdif_select_put,
2232 static void snd_cs46xx_codec_reset (
struct snd_ac97 * ac97)
2234 unsigned long end_time;
2258 unsigned short ext_mid;
2266 if (ext_mid != 0xffff && (ext_mid & 1) != 0)
2286 memset(&ac97, 0,
sizeof(ac97));
2294 snd_cs46xx_codec_write(chip,
AC97_RESET, 0, codec);
2296 if (snd_cs46xx_codec_read(chip,
AC97_RESET, codec) & 0x8000) {
2297 snd_printdd(
"snd_cs46xx: seconadry codec not present\n");
2302 snd_cs46xx_codec_write(chip,
AC97_MASTER, 0x8000, codec);
2303 for (idx = 0; idx < 100; ++
idx) {
2304 if (snd_cs46xx_codec_read(chip,
AC97_MASTER, codec) == 0x8000) {
2310 snd_printdd(
"snd_cs46xx: codec %d detection timeout\n", codec);
2321 #ifdef CONFIG_SND_CS46XX_NEW_DSP
2322 .
reset = snd_cs46xx_codec_reset,
2324 .write = snd_cs46xx_ac97_write,
2325 .read = snd_cs46xx_ac97_read,
2330 snd_printdd(
"snd_cs46xx: detecting primary codec\n");
2333 chip->
ac97_bus->private_free = snd_cs46xx_mixer_free_ac97_bus;
2339 #ifdef CONFIG_SND_CS46XX_NEW_DSP
2340 snd_printdd(
"snd_cs46xx: detecting seconadry codec\n");
2347 for (idx = 0; idx <
ARRAY_SIZE(snd_cs46xx_controls); idx++) {
2351 kctl->
id.device = spdif_device;
2357 memset(&
id, 0,
sizeof(
id));
2362 #ifdef CONFIG_SND_CS46XX_NEW_DSP
2365 if (id2 == 0x592b || id2 == 0x592d) {
2375 snd_printdd (
"calling chip->mixer_init(chip);\n");
2390 static void snd_cs46xx_midi_reset(
struct snd_cs46xx *chip)
2407 snd_cs46xx_midi_reset(chip);
2423 snd_cs46xx_midi_reset(chip);
2444 snd_cs46xx_midi_reset(chip);
2460 snd_cs46xx_midi_reset(chip);
2472 unsigned long flags;
2487 spin_unlock_irqrestore(&chip->
reg_lock, flags);
2492 unsigned long flags;
2502 (snd_cs46xx_peekBA0(chip,
BA0_MIDSR) & MIDSR_TBF) == 0) {
2506 snd_cs46xx_pokeBA0(chip,
BA0_MIDWP, byte);
2517 spin_unlock_irqrestore(&chip->
reg_lock, flags);
2522 .open = snd_cs46xx_midi_output_open,
2523 .close = snd_cs46xx_midi_output_close,
2524 .trigger = snd_cs46xx_midi_output_trigger,
2529 .open = snd_cs46xx_midi_input_open,
2530 .close = snd_cs46xx_midi_input_close,
2531 .trigger = snd_cs46xx_midi_input_trigger,
2548 chip->
rmidi = rmidi;
2559 #if defined(CONFIG_GAMEPORT) || (defined(MODULE) && defined(CONFIG_GAMEPORT_MODULE))
2563 struct snd_cs46xx *chip = gameport_get_port_data(gameport);
2567 snd_cs46xx_pokeBA0(chip,
BA0_JSPT, 0xFF);
2570 static unsigned char snd_cs46xx_gameport_read(
struct gameport *gameport)
2572 struct snd_cs46xx *chip = gameport_get_port_data(gameport);
2576 return snd_cs46xx_peekBA0(chip,
BA0_JSPT);
2579 static int snd_cs46xx_gameport_cooked_read(
struct gameport *gameport,
int *axes,
int *
buttons)
2581 struct snd_cs46xx *chip = gameport_get_port_data(gameport);
2582 unsigned js1, js2, jst;
2587 js1 = snd_cs46xx_peekBA0(chip,
BA0_JSC1);
2588 js2 = snd_cs46xx_peekBA0(chip,
BA0_JSC2);
2589 jst = snd_cs46xx_peekBA0(chip,
BA0_JSPT);
2591 *buttons = (~jst >> 4) & 0x0F;
2598 for(jst=0;jst<4;++jst)
2599 if(axes[jst]==0xFFFF) axes[jst] = -1;
2603 static int snd_cs46xx_gameport_open(
struct gameport *gameport,
int mode)
2618 struct gameport *
gp;
2620 chip->
gameport = gp = gameport_allocate_port();
2622 printk(
KERN_ERR "cs46xx: cannot allocate memory for gameport\n");
2626 gameport_set_name(gp,
"CS46xx Gameport");
2628 gameport_set_dev_parent(gp, &chip->
pci->dev);
2629 gameport_set_port_data(gp, chip);
2631 gp->
open = snd_cs46xx_gameport_open;
2632 gp->
read = snd_cs46xx_gameport_read;
2633 gp->
trigger = snd_cs46xx_gameport_trigger;
2634 gp->
cooked_read = snd_cs46xx_gameport_cooked_read;
2636 snd_cs46xx_pokeBA0(chip,
BA0_JSIO, 0xFF);
2639 gameport_register_port(gp);
2644 static inline void snd_cs46xx_remove_gameport(
struct snd_cs46xx *chip)
2653 static inline void snd_cs46xx_remove_gameport(
struct snd_cs46xx *chip) { }
2656 #ifdef CONFIG_PROC_FS
2662 void *file_private_data,
2664 size_t count, loff_t
pos)
2674 .
read = snd_cs46xx_io_read,
2682 for (idx = 0; idx < 5; idx++) {
2684 if (! snd_card_proc_new(card, region->
name, &entry)) {
2687 entry->
c.
ops = &snd_cs46xx_proc_io_ops;
2692 #ifdef CONFIG_SND_CS46XX_NEW_DSP
2700 #ifdef CONFIG_SND_CS46XX_NEW_DSP
2706 #define snd_cs46xx_proc_init(card, chip)
2707 #define snd_cs46xx_proc_done(chip)
2713 static void snd_cs46xx_hw_stop(
struct snd_cs46xx *chip)
2717 tmp = snd_cs46xx_peek(chip,
BA1_PFIE);
2720 snd_cs46xx_poke(chip,
BA1_PFIE, tmp);
2722 tmp = snd_cs46xx_peek(chip,
BA1_CIE);
2725 snd_cs46xx_poke(chip,
BA1_CIE, tmp);
2730 tmp = snd_cs46xx_peek(chip,
BA1_PCTL);
2731 snd_cs46xx_poke(chip,
BA1_PCTL, tmp & 0x0000ffff);
2736 tmp = snd_cs46xx_peek(chip,
BA1_CCTL);
2737 snd_cs46xx_poke(chip,
BA1_CCTL, tmp & 0xffff0000);
2742 snd_cs46xx_reset(chip);
2744 snd_cs46xx_proc_stop(chip);
2755 tmp = snd_cs46xx_peekBA0(chip,
BA0_CLKCR1) & ~CLKCR1_SWCE;
2760 static int snd_cs46xx_free(
struct snd_cs46xx *chip)
2770 snd_cs46xx_remove_gameport(chip);
2778 snd_cs46xx_hw_stop(chip);
2786 for (idx = 0; idx < 5; idx++) {
2793 #ifdef CONFIG_SND_CS46XX_NEW_DSP
2794 if (chip->dsp_spos_instance) {
2796 chip->dsp_spos_instance =
NULL;
2800 #ifdef CONFIG_PM_SLEEP
2801 kfree(chip->saved_regs);
2809 static int snd_cs46xx_dev_free(
struct snd_device *device)
2812 return snd_cs46xx_free(chip);
2818 static int snd_cs46xx_chip_init(
struct snd_cs46xx *chip)
2834 #ifdef CONFIG_SND_CS46XX_NEW_DSP
2849 #ifdef CONFIG_SND_CS46XX_NEW_DSP
2854 #ifdef CONFIG_SND_CS46XX_NEW_DSP
2864 #ifdef CONFIG_SND_CS46XX_NEW_DSP
2887 snd_cs46xx_pokeBA0(chip,
BA0_PLLM, 0x3a);
2913 snd_cs46xx_clear_serial_FIFOs(chip);
2929 #ifdef CONFIG_SND_CS46XX_NEW_DSP
2944 while (timeout-- > 0) {
2959 #ifdef CONFIG_SND_CS46XX_NEW_DSP
2962 for (count = 0; count < 150; count++) {
2974 snd_printdd(
"cs46xx: never read card ready from secondary AC'97\n");
2983 #ifdef CONFIG_SND_CS46XX_NEW_DSP
2993 while (timeout-- > 0) {
3003 #ifndef CONFIG_SND_CS46XX_NEW_DSP
3048 static void cs46xx_enable_stream_irqs(
struct snd_cs46xx *chip)
3054 tmp = snd_cs46xx_peek(chip,
BA1_PFIE);
3056 snd_cs46xx_poke(chip,
BA1_PFIE, tmp);
3058 tmp = snd_cs46xx_peek(chip,
BA1_CIE);
3061 snd_cs46xx_poke(chip,
BA1_CIE, tmp);
3070 snd_cs46xx_reset(chip);
3074 #ifdef CONFIG_SND_CS46XX_NEW_DSP
3119 tmp = snd_cs46xx_peek(chip,
BA1_PCTL);
3121 snd_cs46xx_poke(chip,
BA1_PCTL, tmp & 0x0000ffff);
3127 tmp = snd_cs46xx_peek(chip,
BA1_CCTL);
3128 chip->
capt.ctl = tmp & 0x0000ffff;
3129 snd_cs46xx_poke(chip,
BA1_CCTL, tmp & 0xffff0000);
3133 snd_cs46xx_set_play_sample_rate(chip, 8000);
3134 snd_cs46xx_set_capture_sample_rate(chip, 8000);
3136 snd_cs46xx_proc_start(chip);
3138 cs46xx_enable_stream_irqs(chip);
3140 #ifndef CONFIG_SND_CS46XX_NEW_DSP
3142 snd_cs46xx_poke(chip,
BA1_PVOL, 0x80008000);
3143 snd_cs46xx_poke(chip,
BA1_CVOL, 0x80008000);
3154 static void amp_none(
struct snd_cs46xx *chip,
int change)
3158 #ifdef CONFIG_SND_CS46XX_NEW_DSP
3159 static int voyetra_setup_eapd_slot(
struct snd_cs46xx *chip)
3165 snd_printdd (
"cs46xx: cs46xx_setup_eapd_slot()+\n");
3173 if (!(tmp & CLKCR1_SWCE)) {
3174 snd_cs46xx_pokeBA0(chip,
BA0_CLKCR1, tmp | CLKCR1_SWCE);
3183 snd_printk (
KERN_ERR "cs46xx: cs46xx_setup_eapd_slot() - no secondary codec configured\n");
3187 modem_power = snd_cs46xx_codec_read (chip,
3190 modem_power &=0xFEFF;
3192 snd_cs46xx_codec_write(chip,
3199 pin_config = snd_cs46xx_codec_read (chip,
3204 snd_cs46xx_codec_write(chip,
3219 valid_slots = snd_cs46xx_peekBA0(chip,
BA0_ACOSV);
3220 valid_slots |= 0x200;
3221 snd_cs46xx_pokeBA0(chip,
BA0_ACOSV, valid_slots);
3223 if ( cs46xx_wait_for_fifo(chip,1) ) {
3232 for(idx = 0x90; idx <= 0x9F; idx++) {
3239 snd_cs46xx_pokeBA0(chip,
BA0_SERBWP, 0x1800);
3244 if ( cs46xx_wait_for_fifo(chip,200) ) {
3245 snd_printdd(
"failed waiting for FIFO at addr (%02X)\n",idx);
3262 cs46xx_wait_for_fifo(chip,200);
3279 static void amp_voyetra(
struct snd_cs46xx *chip,
int change)
3284 #ifdef CONFIG_SND_CS46XX_NEW_DSP
3308 #ifdef CONFIG_SND_CS46XX_NEW_DSP
3310 voyetra_setup_eapd_slot(chip);
3315 static void hercules_init(
struct snd_cs46xx *chip)
3326 static void amp_hercules(
struct snd_cs46xx *chip,
int change)
3347 static void voyetra_mixer_init (
struct snd_cs46xx *chip)
3356 static void hercules_mixer_init (
struct snd_cs46xx *chip)
3358 #ifdef CONFIG_SND_CS46XX_NEW_DSP
3365 hercules_init(chip);
3369 #ifdef CONFIG_SND_CS46XX_NEW_DSP
3373 for (idx = 0 ; idx <
ARRAY_SIZE(snd_hercules_controls); idx++) {
3376 kctl =
snd_ctl_new1(&snd_hercules_controls[idx], chip);
3378 printk (
KERN_ERR "cs46xx: failed to initialize Hercules mixer (%d)\n",err);
3391 static void amp_voyetra_4294(
struct snd_cs46xx *chip,
int change)
3397 snd_cs46xx_codec_write(chip, 0x4C,
3398 snd_cs46xx_codec_read(chip, 0x4C) & 0xFE7F);
3399 snd_cs46xx_codec_write(chip, 0x4E,
3400 snd_cs46xx_codec_read(chip, 0x4E) | 0x0180);
3402 snd_cs46xx_codec_write(chip, 0x54,
3403 snd_cs46xx_codec_read(chip, 0x54) & ~0x0180);
3405 snd_cs46xx_codec_write(chip, 0x54,
3406 snd_cs46xx_codec_read(chip, 0x54) | 0x0180);
3421 static void clkrun_hack(
struct snd_cs46xx *chip,
int change)
3438 if (nval != control)
3446 static void clkrun_init(
struct snd_cs46xx *chip)
3459 pci_read_config_byte(pdev, 0x41, &pp);
3484 .name =
"Genius Soundmaker 128 value",
3492 .mixer_init = voyetra_mixer_init,
3497 .name =
"Mitac MI6020/21",
3504 .name =
"Hercules Game Theatre XP",
3505 .amp = amp_hercules,
3506 .mixer_init = hercules_mixer_init,
3511 .name =
"Hercules Game Theatre XP",
3512 .amp = amp_hercules,
3513 .mixer_init = hercules_mixer_init,
3518 .name =
"Hercules Game Theatre XP",
3519 .amp = amp_hercules,
3520 .mixer_init = hercules_mixer_init,
3526 .name =
"Hercules Game Theatre XP",
3527 .amp = amp_hercules,
3528 .mixer_init = hercules_mixer_init,
3533 .name =
"Hercules Game Theatre XP",
3534 .amp = amp_hercules,
3535 .mixer_init = hercules_mixer_init,
3540 .name =
"Hercules Game Theatre XP",
3541 .amp = amp_hercules,
3542 .mixer_init = hercules_mixer_init,
3548 .name =
"Hercules Gamesurround Fortissimo II",
3553 .name =
"Hercules Gamesurround Fortissimo III 7.1",
3559 .name =
"Terratec DMX XFire 1024",
3564 .name =
"Terratec SiXPack 5.1",
3570 .name =
"Thinkpad 570",
3571 .init = clkrun_init,
3572 .active = clkrun_hack,
3577 .name =
"Thinkpad 600X/A20/T20",
3578 .init = clkrun_init,
3579 .active = clkrun_hack,
3584 .name =
"Thinkpad 600E (unsupported)",
3593 #ifdef CONFIG_PM_SLEEP
3602 static int snd_cs46xx_suspend(
struct device *
dev)
3611 snd_pcm_suspend_all(chip->
pcm);
3620 chip->saved_regs[i] = snd_cs46xx_peekBA0(chip, saved_regs[i]);
3625 snd_cs46xx_hw_stop(chip);
3636 static int snd_cs46xx_resume(
struct device *dev)
3642 #ifdef CONFIG_SND_CS46XX_NEW_DSP
3651 "disabling device\n");
3661 snd_cs46xx_chip_init(chip);
3663 snd_cs46xx_reset(chip);
3664 #ifdef CONFIG_SND_CS46XX_NEW_DSP
3665 cs46xx_dsp_resume(chip);
3668 snd_cs46xx_pokeBA0(chip, saved_regs[i], chip->saved_regs[i]);
3674 snd_cs46xx_codec_write(chip, BA0_AC97_GENERAL_PURPOSE,
3675 chip->ac97_general_purpose);
3677 chip->ac97_powerdown);
3679 snd_cs46xx_codec_write(chip, BA0_AC97_POWERDOWN,
3680 chip->ac97_powerdown);
3690 tmp = snd_cs46xx_peek(chip,
BA1_CCTL);
3691 chip->
capt.ctl = tmp & 0x0000ffff;
3692 snd_cs46xx_poke(chip,
BA1_CCTL, tmp & 0xffff0000);
3697 snd_cs46xx_set_play_sample_rate(chip, 8000);
3698 snd_cs46xx_set_capture_sample_rate(chip, 8000);
3699 snd_cs46xx_proc_start(chip);
3701 cs46xx_enable_stream_irqs(chip);
3722 int external_amp,
int thinkpad,
3729 u16 ss_card, ss_vendor;
3746 #ifdef CONFIG_SND_CS46XX_NEW_DSP
3758 snd_cs46xx_free(chip);
3791 for (cp = &cards[0]; cp->
name; cp++) {
3792 if (cp->
vendor == ss_vendor && cp->
id == ss_card) {
3825 for (idx = 0; idx < 5; idx++) {
3831 snd_cs46xx_free(chip);
3837 snd_cs46xx_free(chip);
3843 KBUILD_MODNAME, chip)) {
3845 snd_cs46xx_free(chip);
3850 #ifdef CONFIG_SND_CS46XX_NEW_DSP
3852 if (chip->dsp_spos_instance ==
NULL) {
3853 snd_cs46xx_free(chip);
3858 err = snd_cs46xx_chip_init(chip);
3860 snd_cs46xx_free(chip);
3865 snd_cs46xx_free(chip);
3871 #ifdef CONFIG_PM_SLEEP
3872 chip->saved_regs =
kmalloc(
sizeof(*chip->saved_regs) *
3874 if (!chip->saved_regs) {
3875 snd_cs46xx_free(chip);