diff options
Diffstat (limited to 'sound/pci/cmipci.c')
-rw-r--r-- | sound/pci/cmipci.c | 121 |
1 files changed, 90 insertions, 31 deletions
diff --git a/sound/pci/cmipci.c b/sound/pci/cmipci.c index 6832649879ce..135f30860753 100644 --- a/sound/pci/cmipci.c +++ b/sound/pci/cmipci.c | |||
@@ -20,7 +20,6 @@ | |||
20 | /* Does not work. Warning may block system in capture mode */ | 20 | /* Does not work. Warning may block system in capture mode */ |
21 | /* #define USE_VAR48KRATE */ | 21 | /* #define USE_VAR48KRATE */ |
22 | 22 | ||
23 | #include <sound/driver.h> | ||
24 | #include <asm/io.h> | 23 | #include <asm/io.h> |
25 | #include <linux/delay.h> | 24 | #include <linux/delay.h> |
26 | #include <linux/interrupt.h> | 25 | #include <linux/interrupt.h> |
@@ -150,6 +149,8 @@ MODULE_PARM_DESC(joystick_port, "Joystick port address."); | |||
150 | #define CM_CH0_SRATE_176K 0x00000200 | 149 | #define CM_CH0_SRATE_176K 0x00000200 |
151 | #define CM_CH0_SRATE_96K 0x00000200 /* model 055? */ | 150 | #define CM_CH0_SRATE_96K 0x00000200 /* model 055? */ |
152 | #define CM_CH0_SRATE_88K 0x00000100 | 151 | #define CM_CH0_SRATE_88K 0x00000100 |
152 | #define CM_CH0_SRATE_128K 0x00000300 | ||
153 | #define CM_CH0_SRATE_MASK 0x00000300 | ||
153 | 154 | ||
154 | #define CM_SPDIF_INVERSE2 0x00000080 /* model 055? */ | 155 | #define CM_SPDIF_INVERSE2 0x00000080 /* model 055? */ |
155 | #define CM_DBLSPDS 0x00000040 /* double SPDIF sample rate 88.2/96 */ | 156 | #define CM_DBLSPDS 0x00000040 /* double SPDIF sample rate 88.2/96 */ |
@@ -246,10 +247,9 @@ MODULE_PARM_DESC(joystick_port, "Joystick port address."); | |||
246 | #define CM_MMODE_MASK 0x00000E00 /* model DAA interface mode */ | 247 | #define CM_MMODE_MASK 0x00000E00 /* model DAA interface mode */ |
247 | #define CM_SPDIF_SELECT2 0x00000100 /* for model > 039 ? */ | 248 | #define CM_SPDIF_SELECT2 0x00000100 /* for model > 039 ? */ |
248 | #define CM_ENCENTER 0x00000080 | 249 | #define CM_ENCENTER 0x00000080 |
249 | #define CM_FLINKON 0x00000080 /* force modem link detection on, model 037 */ | 250 | #define CM_FLINKON 0x00000040 /* force modem link detection on, model 037 */ |
250 | #define CM_MUTECH1 0x00000040 /* mute PCI ch1 to DAC */ | 251 | #define CM_MUTECH1 0x00000040 /* mute PCI ch1 to DAC */ |
251 | #define CM_FLINKOFF 0x00000040 /* force modem link detection off, model 037 */ | 252 | #define CM_FLINKOFF 0x00000020 /* force modem link detection off, model 037 */ |
252 | #define CM_UNKNOWN_18_5 0x00000020 /* ? */ | ||
253 | #define CM_MIDSMP 0x00000010 /* 1/2 interpolation at front end DAC */ | 253 | #define CM_MIDSMP 0x00000010 /* 1/2 interpolation at front end DAC */ |
254 | #define CM_UPDDMA_MASK 0x0000000C /* TDMA position update notification */ | 254 | #define CM_UPDDMA_MASK 0x0000000C /* TDMA position update notification */ |
255 | #define CM_UPDDMA_2048 0x00000000 | 255 | #define CM_UPDDMA_2048 0x00000000 |
@@ -474,6 +474,7 @@ struct cmipci { | |||
474 | unsigned int can_ac3_sw: 1; | 474 | unsigned int can_ac3_sw: 1; |
475 | unsigned int can_ac3_hw: 1; | 475 | unsigned int can_ac3_hw: 1; |
476 | unsigned int can_multi_ch: 1; | 476 | unsigned int can_multi_ch: 1; |
477 | unsigned int can_96k: 1; /* samplerate above 48k */ | ||
477 | unsigned int do_soft_ac3: 1; | 478 | unsigned int do_soft_ac3: 1; |
478 | 479 | ||
479 | unsigned int spdif_playback_avail: 1; /* spdif ready? */ | 480 | unsigned int spdif_playback_avail: 1; /* spdif ready? */ |
@@ -604,8 +605,6 @@ static unsigned int snd_cmipci_rate_freq(unsigned int rate) | |||
604 | { | 605 | { |
605 | unsigned int i; | 606 | unsigned int i; |
606 | 607 | ||
607 | if (rate > 48000) | ||
608 | rate /= 2; | ||
609 | for (i = 0; i < ARRAY_SIZE(rates); i++) { | 608 | for (i = 0; i < ARRAY_SIZE(rates); i++) { |
610 | if (rates[i] == rate) | 609 | if (rates[i] == rate) |
611 | return i; | 610 | return i; |
@@ -783,7 +782,7 @@ static int set_dac_channels(struct cmipci *cm, struct cmipci_pcm *rec, int chann | |||
783 | static int snd_cmipci_pcm_prepare(struct cmipci *cm, struct cmipci_pcm *rec, | 782 | static int snd_cmipci_pcm_prepare(struct cmipci *cm, struct cmipci_pcm *rec, |
784 | struct snd_pcm_substream *substream) | 783 | struct snd_pcm_substream *substream) |
785 | { | 784 | { |
786 | unsigned int reg, freq, val; | 785 | unsigned int reg, freq, freq_ext, val; |
787 | unsigned int period_size; | 786 | unsigned int period_size; |
788 | struct snd_pcm_runtime *runtime = substream->runtime; | 787 | struct snd_pcm_runtime *runtime = substream->runtime; |
789 | 788 | ||
@@ -831,7 +830,17 @@ static int snd_cmipci_pcm_prepare(struct cmipci *cm, struct cmipci_pcm *rec, | |||
831 | //snd_printd("cmipci: functrl0 = %08x\n", cm->ctrl); | 830 | //snd_printd("cmipci: functrl0 = %08x\n", cm->ctrl); |
832 | 831 | ||
833 | /* set sample rate */ | 832 | /* set sample rate */ |
834 | freq = snd_cmipci_rate_freq(runtime->rate); | 833 | freq = 0; |
834 | freq_ext = 0; | ||
835 | if (runtime->rate > 48000) | ||
836 | switch (runtime->rate) { | ||
837 | case 88200: freq_ext = CM_CH0_SRATE_88K; break; | ||
838 | case 96000: freq_ext = CM_CH0_SRATE_96K; break; | ||
839 | case 128000: freq_ext = CM_CH0_SRATE_128K; break; | ||
840 | default: snd_BUG(); break; | ||
841 | } | ||
842 | else | ||
843 | freq = snd_cmipci_rate_freq(runtime->rate); | ||
835 | val = snd_cmipci_read(cm, CM_REG_FUNCTRL1); | 844 | val = snd_cmipci_read(cm, CM_REG_FUNCTRL1); |
836 | if (rec->ch) { | 845 | if (rec->ch) { |
837 | val &= ~CM_DSFC_MASK; | 846 | val &= ~CM_DSFC_MASK; |
@@ -852,19 +861,20 @@ static int snd_cmipci_pcm_prepare(struct cmipci *cm, struct cmipci_pcm *rec, | |||
852 | val &= ~CM_CH0FMT_MASK; | 861 | val &= ~CM_CH0FMT_MASK; |
853 | val |= rec->fmt << CM_CH0FMT_SHIFT; | 862 | val |= rec->fmt << CM_CH0FMT_SHIFT; |
854 | } | 863 | } |
855 | if (cm->chip_version == 68) { | 864 | if (cm->can_96k) { |
856 | if (runtime->rate == 88200) | 865 | val &= ~(CM_CH0_SRATE_MASK << (rec->ch * 2)); |
857 | val |= CM_CH0_SRATE_88K << (rec->ch * 2); | 866 | val |= freq_ext << (rec->ch * 2); |
858 | else | ||
859 | val &= ~(CM_CH0_SRATE_88K << (rec->ch * 2)); | ||
860 | if (runtime->rate == 96000) | ||
861 | val |= CM_CH0_SRATE_96K << (rec->ch * 2); | ||
862 | else | ||
863 | val &= ~(CM_CH0_SRATE_96K << (rec->ch * 2)); | ||
864 | } | 867 | } |
865 | snd_cmipci_write(cm, CM_REG_CHFORMAT, val); | 868 | snd_cmipci_write(cm, CM_REG_CHFORMAT, val); |
866 | //snd_printd("cmipci: chformat = %08x\n", val); | 869 | //snd_printd("cmipci: chformat = %08x\n", val); |
867 | 870 | ||
871 | if (!rec->is_dac && cm->chip_version) { | ||
872 | if (runtime->rate > 44100) | ||
873 | snd_cmipci_set_bit(cm, CM_REG_EXT_MISC, CM_ADC48K44K); | ||
874 | else | ||
875 | snd_cmipci_clear_bit(cm, CM_REG_EXT_MISC, CM_ADC48K44K); | ||
876 | } | ||
877 | |||
868 | rec->running = 0; | 878 | rec->running = 0; |
869 | spin_unlock_irq(&cm->reg_lock); | 879 | spin_unlock_irq(&cm->reg_lock); |
870 | 880 | ||
@@ -1281,7 +1291,7 @@ static int snd_cmipci_playback_prepare(struct snd_pcm_substream *substream) | |||
1281 | int rate = substream->runtime->rate; | 1291 | int rate = substream->runtime->rate; |
1282 | int err, do_spdif, do_ac3 = 0; | 1292 | int err, do_spdif, do_ac3 = 0; |
1283 | 1293 | ||
1284 | do_spdif = (rate >= 44100 && | 1294 | do_spdif = (rate >= 44100 && rate <= 96000 && |
1285 | substream->runtime->format == SNDRV_PCM_FORMAT_S16_LE && | 1295 | substream->runtime->format == SNDRV_PCM_FORMAT_S16_LE && |
1286 | substream->runtime->channels == 2); | 1296 | substream->runtime->channels == 2); |
1287 | if (do_spdif && cm->can_ac3_hw) | 1297 | if (do_spdif && cm->can_ac3_hw) |
@@ -1337,10 +1347,8 @@ static void snd_cmipci_silence_hack(struct cmipci *cm, struct cmipci_pcm *rec) | |||
1337 | val = snd_cmipci_read(cm, CM_REG_CHFORMAT); | 1347 | val = snd_cmipci_read(cm, CM_REG_CHFORMAT); |
1338 | val &= ~(CM_CH0FMT_MASK << (rec->ch * 2)); | 1348 | val &= ~(CM_CH0FMT_MASK << (rec->ch * 2)); |
1339 | val |= (3 << CM_CH0FMT_SHIFT) << (rec->ch * 2); | 1349 | val |= (3 << CM_CH0FMT_SHIFT) << (rec->ch * 2); |
1340 | if (cm->chip_version == 68) { | 1350 | if (cm->can_96k) |
1341 | val &= ~(CM_CH0_SRATE_88K << (rec->ch * 2)); | 1351 | val &= ~(CM_CH0_SRATE_MASK << (rec->ch * 2)); |
1342 | val &= ~(CM_CH0_SRATE_96K << (rec->ch * 2)); | ||
1343 | } | ||
1344 | snd_cmipci_write(cm, CM_REG_CHFORMAT, val); | 1352 | snd_cmipci_write(cm, CM_REG_CHFORMAT, val); |
1345 | 1353 | ||
1346 | /* start stream (we don't need interrupts) */ | 1354 | /* start stream (we don't need interrupts) */ |
@@ -1392,6 +1400,17 @@ static int snd_cmipci_capture_spdif_prepare(struct snd_pcm_substream *substream) | |||
1392 | 1400 | ||
1393 | spin_lock_irq(&cm->reg_lock); | 1401 | spin_lock_irq(&cm->reg_lock); |
1394 | snd_cmipci_set_bit(cm, CM_REG_FUNCTRL1, CM_CAPTURE_SPDF); | 1402 | snd_cmipci_set_bit(cm, CM_REG_FUNCTRL1, CM_CAPTURE_SPDF); |
1403 | if (cm->can_96k) { | ||
1404 | if (substream->runtime->rate > 48000) | ||
1405 | snd_cmipci_set_bit(cm, CM_REG_CHFORMAT, CM_DBLSPDS); | ||
1406 | else | ||
1407 | snd_cmipci_clear_bit(cm, CM_REG_CHFORMAT, CM_DBLSPDS); | ||
1408 | } | ||
1409 | if (snd_pcm_format_width(substream->runtime->format) > 16) | ||
1410 | snd_cmipci_set_bit(cm, CM_REG_MISC_CTRL, CM_SPD32SEL); | ||
1411 | else | ||
1412 | snd_cmipci_clear_bit(cm, CM_REG_MISC_CTRL, CM_SPD32SEL); | ||
1413 | |||
1395 | spin_unlock_irq(&cm->reg_lock); | 1414 | spin_unlock_irq(&cm->reg_lock); |
1396 | 1415 | ||
1397 | return snd_cmipci_pcm_prepare(cm, &cm->channel[CM_CH_CAPT], substream); | 1416 | return snd_cmipci_pcm_prepare(cm, &cm->channel[CM_CH_CAPT], substream); |
@@ -1403,6 +1422,7 @@ static int snd_cmipci_capture_spdif_hw_free(struct snd_pcm_substream *subs) | |||
1403 | 1422 | ||
1404 | spin_lock_irq(&cm->reg_lock); | 1423 | spin_lock_irq(&cm->reg_lock); |
1405 | snd_cmipci_clear_bit(cm, CM_REG_FUNCTRL1, CM_CAPTURE_SPDF); | 1424 | snd_cmipci_clear_bit(cm, CM_REG_FUNCTRL1, CM_CAPTURE_SPDF); |
1425 | snd_cmipci_clear_bit(cm, CM_REG_MISC_CTRL, CM_SPD32SEL); | ||
1406 | spin_unlock_irq(&cm->reg_lock); | 1426 | spin_unlock_irq(&cm->reg_lock); |
1407 | 1427 | ||
1408 | return snd_cmipci_hw_free(subs); | 1428 | return snd_cmipci_hw_free(subs); |
@@ -1554,7 +1574,8 @@ static struct snd_pcm_hardware snd_cmipci_capture_spdif = | |||
1554 | .info = (SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED | | 1574 | .info = (SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED | |
1555 | SNDRV_PCM_INFO_BLOCK_TRANSFER | SNDRV_PCM_INFO_PAUSE | | 1575 | SNDRV_PCM_INFO_BLOCK_TRANSFER | SNDRV_PCM_INFO_PAUSE | |
1556 | SNDRV_PCM_INFO_RESUME | SNDRV_PCM_INFO_MMAP_VALID), | 1576 | SNDRV_PCM_INFO_RESUME | SNDRV_PCM_INFO_MMAP_VALID), |
1557 | .formats = SNDRV_PCM_FMTBIT_S16_LE, | 1577 | .formats = SNDRV_PCM_FMTBIT_S16_LE | |
1578 | SNDRV_PCM_FMTBIT_IEC958_SUBFRAME_LE, | ||
1558 | .rates = SNDRV_PCM_RATE_44100 | SNDRV_PCM_RATE_48000, | 1579 | .rates = SNDRV_PCM_RATE_44100 | SNDRV_PCM_RATE_48000, |
1559 | .rate_min = 44100, | 1580 | .rate_min = 44100, |
1560 | .rate_max = 48000, | 1581 | .rate_max = 48000, |
@@ -1568,6 +1589,14 @@ static struct snd_pcm_hardware snd_cmipci_capture_spdif = | |||
1568 | .fifo_size = 0, | 1589 | .fifo_size = 0, |
1569 | }; | 1590 | }; |
1570 | 1591 | ||
1592 | static unsigned int rate_constraints[] = { 5512, 8000, 11025, 16000, 22050, | ||
1593 | 32000, 44100, 48000, 88200, 96000, 128000 }; | ||
1594 | static struct snd_pcm_hw_constraint_list hw_constraints_rates = { | ||
1595 | .count = ARRAY_SIZE(rate_constraints), | ||
1596 | .list = rate_constraints, | ||
1597 | .mask = 0, | ||
1598 | }; | ||
1599 | |||
1571 | /* | 1600 | /* |
1572 | * check device open/close | 1601 | * check device open/close |
1573 | */ | 1602 | */ |
@@ -1637,6 +1666,13 @@ static int snd_cmipci_playback_open(struct snd_pcm_substream *substream) | |||
1637 | runtime->hw.rates |= SNDRV_PCM_RATE_88200 | | 1666 | runtime->hw.rates |= SNDRV_PCM_RATE_88200 | |
1638 | SNDRV_PCM_RATE_96000; | 1667 | SNDRV_PCM_RATE_96000; |
1639 | runtime->hw.rate_max = 96000; | 1668 | runtime->hw.rate_max = 96000; |
1669 | } else if (cm->chip_version == 55) { | ||
1670 | err = snd_pcm_hw_constraint_list(runtime, 0, | ||
1671 | SNDRV_PCM_HW_PARAM_RATE, &hw_constraints_rates); | ||
1672 | if (err < 0) | ||
1673 | return err; | ||
1674 | runtime->hw.rates |= SNDRV_PCM_RATE_KNOT; | ||
1675 | runtime->hw.rate_max = 128000; | ||
1640 | } | 1676 | } |
1641 | snd_pcm_hw_constraint_minmax(runtime, SNDRV_PCM_HW_PARAM_BUFFER_SIZE, 0, 0x10000); | 1677 | snd_pcm_hw_constraint_minmax(runtime, SNDRV_PCM_HW_PARAM_BUFFER_SIZE, 0, 0x10000); |
1642 | cm->dig_pcm_status = cm->dig_status; | 1678 | cm->dig_pcm_status = cm->dig_status; |
@@ -1655,6 +1691,13 @@ static int snd_cmipci_capture_open(struct snd_pcm_substream *substream) | |||
1655 | if (cm->chip_version == 68) { // 8768 only supports 44k/48k recording | 1691 | if (cm->chip_version == 68) { // 8768 only supports 44k/48k recording |
1656 | runtime->hw.rate_min = 41000; | 1692 | runtime->hw.rate_min = 41000; |
1657 | runtime->hw.rates = SNDRV_PCM_RATE_44100 | SNDRV_PCM_RATE_48000; | 1693 | runtime->hw.rates = SNDRV_PCM_RATE_44100 | SNDRV_PCM_RATE_48000; |
1694 | } else if (cm->chip_version == 55) { | ||
1695 | err = snd_pcm_hw_constraint_list(runtime, 0, | ||
1696 | SNDRV_PCM_HW_PARAM_RATE, &hw_constraints_rates); | ||
1697 | if (err < 0) | ||
1698 | return err; | ||
1699 | runtime->hw.rates |= SNDRV_PCM_RATE_KNOT; | ||
1700 | runtime->hw.rate_max = 128000; | ||
1658 | } | 1701 | } |
1659 | snd_pcm_hw_constraint_minmax(runtime, SNDRV_PCM_HW_PARAM_BUFFER_SIZE, 0, 0x10000); | 1702 | snd_pcm_hw_constraint_minmax(runtime, SNDRV_PCM_HW_PARAM_BUFFER_SIZE, 0, 0x10000); |
1660 | return 0; | 1703 | return 0; |
@@ -1686,6 +1729,13 @@ static int snd_cmipci_playback2_open(struct snd_pcm_substream *substream) | |||
1686 | runtime->hw.rates |= SNDRV_PCM_RATE_88200 | | 1729 | runtime->hw.rates |= SNDRV_PCM_RATE_88200 | |
1687 | SNDRV_PCM_RATE_96000; | 1730 | SNDRV_PCM_RATE_96000; |
1688 | runtime->hw.rate_max = 96000; | 1731 | runtime->hw.rate_max = 96000; |
1732 | } else if (cm->chip_version == 55) { | ||
1733 | err = snd_pcm_hw_constraint_list(runtime, 0, | ||
1734 | SNDRV_PCM_HW_PARAM_RATE, &hw_constraints_rates); | ||
1735 | if (err < 0) | ||
1736 | return err; | ||
1737 | runtime->hw.rates |= SNDRV_PCM_RATE_KNOT; | ||
1738 | runtime->hw.rate_max = 128000; | ||
1689 | } | 1739 | } |
1690 | snd_pcm_hw_constraint_minmax(runtime, SNDRV_PCM_HW_PARAM_BUFFER_SIZE, 0, 0x10000); | 1740 | snd_pcm_hw_constraint_minmax(runtime, SNDRV_PCM_HW_PARAM_BUFFER_SIZE, 0, 0x10000); |
1691 | return 0; | 1741 | return 0; |
@@ -1705,7 +1755,7 @@ static int snd_cmipci_playback_spdif_open(struct snd_pcm_substream *substream) | |||
1705 | runtime->hw.formats |= SNDRV_PCM_FMTBIT_S32_LE; | 1755 | runtime->hw.formats |= SNDRV_PCM_FMTBIT_S32_LE; |
1706 | snd_pcm_hw_constraint_msbits(runtime, 0, 32, 24); | 1756 | snd_pcm_hw_constraint_msbits(runtime, 0, 32, 24); |
1707 | } | 1757 | } |
1708 | if (cm->chip_version == 68) { | 1758 | if (cm->can_96k) { |
1709 | runtime->hw.rates |= SNDRV_PCM_RATE_88200 | | 1759 | runtime->hw.rates |= SNDRV_PCM_RATE_88200 | |
1710 | SNDRV_PCM_RATE_96000; | 1760 | SNDRV_PCM_RATE_96000; |
1711 | runtime->hw.rate_max = 96000; | 1761 | runtime->hw.rate_max = 96000; |
@@ -1727,6 +1777,11 @@ static int snd_cmipci_capture_spdif_open(struct snd_pcm_substream *substream) | |||
1727 | if ((err = open_device_check(cm, CM_OPEN_SPDIF_CAPTURE, substream)) < 0) /* use channel B */ | 1777 | if ((err = open_device_check(cm, CM_OPEN_SPDIF_CAPTURE, substream)) < 0) /* use channel B */ |
1728 | return err; | 1778 | return err; |
1729 | runtime->hw = snd_cmipci_capture_spdif; | 1779 | runtime->hw = snd_cmipci_capture_spdif; |
1780 | if (cm->can_96k && !(cm->chip_version == 68)) { | ||
1781 | runtime->hw.rates |= SNDRV_PCM_RATE_88200 | | ||
1782 | SNDRV_PCM_RATE_96000; | ||
1783 | runtime->hw.rate_max = 96000; | ||
1784 | } | ||
1730 | snd_pcm_hw_constraint_minmax(runtime, SNDRV_PCM_HW_PARAM_BUFFER_SIZE, 0, 0x40000); | 1785 | snd_pcm_hw_constraint_minmax(runtime, SNDRV_PCM_HW_PARAM_BUFFER_SIZE, 0, 0x40000); |
1731 | return 0; | 1786 | return 0; |
1732 | } | 1787 | } |
@@ -2595,10 +2650,8 @@ static struct snd_kcontrol_new snd_cmipci_extra_mixer_switches[] __devinitdata = | |||
2595 | }; | 2650 | }; |
2596 | 2651 | ||
2597 | /* card control switches */ | 2652 | /* card control switches */ |
2598 | static struct snd_kcontrol_new snd_cmipci_control_switches[] __devinitdata = { | 2653 | static struct snd_kcontrol_new snd_cmipci_modem_switch __devinitdata = |
2599 | // DEFINE_CARD_SWITCH("Joystick", joystick), /* now module option */ | 2654 | DEFINE_CARD_SWITCH("Modem", modem); |
2600 | DEFINE_CARD_SWITCH("Modem", modem), | ||
2601 | }; | ||
2602 | 2655 | ||
2603 | 2656 | ||
2604 | static int __devinit snd_cmipci_mixer_new(struct cmipci *cm, int pcm_spdif_device) | 2657 | static int __devinit snd_cmipci_mixer_new(struct cmipci *cm, int pcm_spdif_device) |
@@ -2679,9 +2732,13 @@ static int __devinit snd_cmipci_mixer_new(struct cmipci *cm, int pcm_spdif_devic | |||
2679 | } | 2732 | } |
2680 | 2733 | ||
2681 | /* card switches */ | 2734 | /* card switches */ |
2682 | sw = snd_cmipci_control_switches; | 2735 | /* |
2683 | for (idx = 0; idx < ARRAY_SIZE(snd_cmipci_control_switches); idx++, sw++) { | 2736 | * newer chips don't have the register bits to force modem link |
2684 | err = snd_ctl_add(cm->card, snd_ctl_new1(sw, cm)); | 2737 | * detection; the bit that was FLINKON now mutes CH1 |
2738 | */ | ||
2739 | if (cm->chip_version < 39) { | ||
2740 | err = snd_ctl_add(cm->card, | ||
2741 | snd_ctl_new1(&snd_cmipci_modem_switch, cm)); | ||
2685 | if (err < 0) | 2742 | if (err < 0) |
2686 | return err; | 2743 | return err; |
2687 | } | 2744 | } |
@@ -2786,9 +2843,11 @@ static void __devinit query_chip(struct cmipci *cm) | |||
2786 | } else if (detect & CM_CHIP_8768) { | 2843 | } else if (detect & CM_CHIP_8768) { |
2787 | cm->chip_version = 68; | 2844 | cm->chip_version = 68; |
2788 | cm->max_channels = 8; | 2845 | cm->max_channels = 8; |
2846 | cm->can_96k = 1; | ||
2789 | } else { | 2847 | } else { |
2790 | cm->chip_version = 55; | 2848 | cm->chip_version = 55; |
2791 | cm->max_channels = 6; | 2849 | cm->max_channels = 6; |
2850 | cm->can_96k = 1; | ||
2792 | } | 2851 | } |
2793 | cm->can_ac3_hw = 1; | 2852 | cm->can_ac3_hw = 1; |
2794 | cm->can_multi_ch = 1; | 2853 | cm->can_multi_ch = 1; |