diff options
author | Clemens Ladisch <clemens@ladisch.de> | 2007-09-03 03:54:55 -0400 |
---|---|---|
committer | Jaroslav Kysela <perex@perex.cz> | 2007-10-16 09:59:43 -0400 |
commit | 8992e18db32f5df55fd4b458def7dccd2a5c3266 (patch) | |
tree | 56b303b35a1fd5d68199d47096c409f752ce707b /sound/pci/cmipci.c | |
parent | f19a82a119b41d4607b63e6fd0412498a87d30bc (diff) |
[ALSA] cmipci: add 96 kHz support
Add support for 88.2 kHz and 96 kHz analog and digital playback on
CMI8768/CMI8770 chips.
Signed-off-by: Clemens Ladisch <clemens@ladisch.de>
Signed-off-by: Jaroslav Kysela <perex@suse.cz>
Diffstat (limited to 'sound/pci/cmipci.c')
-rw-r--r-- | sound/pci/cmipci.c | 38 |
1 files changed, 35 insertions, 3 deletions
diff --git a/sound/pci/cmipci.c b/sound/pci/cmipci.c index 6d3a0abadd75..af266eb83059 100644 --- a/sound/pci/cmipci.c +++ b/sound/pci/cmipci.c | |||
@@ -135,11 +135,14 @@ MODULE_PARM_DESC(joystick_port, "Joystick port address."); | |||
135 | #define CM_ADCDACLEN_280 0x00003000 | 135 | #define CM_ADCDACLEN_280 0x00003000 |
136 | 136 | ||
137 | #define CM_CH1_SRATE_176K 0x00000800 | 137 | #define CM_CH1_SRATE_176K 0x00000800 |
138 | #define CM_CH1_SRATE_96K 0x00000800 /* model 055? */ | ||
138 | #define CM_CH1_SRATE_88K 0x00000400 | 139 | #define CM_CH1_SRATE_88K 0x00000400 |
139 | #define CM_CH0_SRATE_176K 0x00000200 | 140 | #define CM_CH0_SRATE_176K 0x00000200 |
141 | #define CM_CH0_SRATE_96K 0x00000200 /* model 055? */ | ||
140 | #define CM_CH0_SRATE_88K 0x00000100 | 142 | #define CM_CH0_SRATE_88K 0x00000100 |
141 | 143 | ||
142 | #define CM_SPDIF_INVERSE2 0x00000080 /* model 055? */ | 144 | #define CM_SPDIF_INVERSE2 0x00000080 /* model 055? */ |
145 | #define CM_DBLSPDS 0x00000040 | ||
143 | 146 | ||
144 | #define CM_CH1FMT_MASK 0x0000000C | 147 | #define CM_CH1FMT_MASK 0x0000000C |
145 | #define CM_CH1FMT_SHIFT 2 | 148 | #define CM_CH1FMT_SHIFT 2 |
@@ -812,6 +815,16 @@ static int snd_cmipci_pcm_prepare(struct cmipci *cm, struct cmipci_pcm *rec, | |||
812 | val &= ~CM_CH0FMT_MASK; | 815 | val &= ~CM_CH0FMT_MASK; |
813 | val |= rec->fmt << CM_CH0FMT_SHIFT; | 816 | val |= rec->fmt << CM_CH0FMT_SHIFT; |
814 | } | 817 | } |
818 | if (cm->chip_version == 68) { | ||
819 | if (runtime->rate == 88200) | ||
820 | val |= CM_CH0_SRATE_88K << (rec->ch * 2); | ||
821 | else | ||
822 | val &= ~(CM_CH0_SRATE_88K << (rec->ch * 2)); | ||
823 | if (runtime->rate == 96000) | ||
824 | val |= CM_CH0_SRATE_96K << (rec->ch * 2); | ||
825 | else | ||
826 | val &= ~(CM_CH0_SRATE_96K << (rec->ch * 2)); | ||
827 | } | ||
815 | snd_cmipci_write(cm, CM_REG_CHFORMAT, val); | 828 | snd_cmipci_write(cm, CM_REG_CHFORMAT, val); |
816 | //snd_printd("cmipci: chformat = %08x\n", val); | 829 | //snd_printd("cmipci: chformat = %08x\n", val); |
817 | 830 | ||
@@ -1198,15 +1211,19 @@ static int setup_spdif_playback(struct cmipci *cm, struct snd_pcm_substream *sub | |||
1198 | snd_cmipci_set_bit(cm, CM_REG_FUNCTRL1, CM_PLAYBACK_SPDF); | 1211 | snd_cmipci_set_bit(cm, CM_REG_FUNCTRL1, CM_PLAYBACK_SPDF); |
1199 | setup_ac3(cm, subs, do_ac3, rate); | 1212 | setup_ac3(cm, subs, do_ac3, rate); |
1200 | 1213 | ||
1201 | if (rate == 48000) | 1214 | if (rate == 48000 || rate == 96000) |
1202 | snd_cmipci_set_bit(cm, CM_REG_MISC_CTRL, CM_SPDIF48K | CM_SPDF_AC97); | 1215 | snd_cmipci_set_bit(cm, CM_REG_MISC_CTRL, CM_SPDIF48K | CM_SPDF_AC97); |
1203 | else | 1216 | else |
1204 | snd_cmipci_clear_bit(cm, CM_REG_MISC_CTRL, CM_SPDIF48K | CM_SPDF_AC97); | 1217 | snd_cmipci_clear_bit(cm, CM_REG_MISC_CTRL, CM_SPDIF48K | CM_SPDF_AC97); |
1205 | 1218 | if (rate > 48000) | |
1219 | snd_cmipci_set_bit(cm, CM_REG_CHFORMAT, CM_DBLSPDS); | ||
1220 | else | ||
1221 | snd_cmipci_clear_bit(cm, CM_REG_CHFORMAT, CM_DBLSPDS); | ||
1206 | } else { | 1222 | } else { |
1207 | /* they are controlled via "IEC958 Output Switch" */ | 1223 | /* they are controlled via "IEC958 Output Switch" */ |
1208 | /* snd_cmipci_clear_bit(cm, CM_REG_LEGACY_CTRL, CM_ENSPDOUT); */ | 1224 | /* snd_cmipci_clear_bit(cm, CM_REG_LEGACY_CTRL, CM_ENSPDOUT); */ |
1209 | /* snd_cmipci_clear_bit(cm, CM_REG_FUNCTRL1, CM_SPDO2DAC); */ | 1225 | /* snd_cmipci_clear_bit(cm, CM_REG_FUNCTRL1, CM_SPDO2DAC); */ |
1226 | snd_cmipci_clear_bit(cm, CM_REG_CHFORMAT, CM_DBLSPDS); | ||
1210 | snd_cmipci_clear_bit(cm, CM_REG_FUNCTRL1, CM_PLAYBACK_SPDF); | 1227 | snd_cmipci_clear_bit(cm, CM_REG_FUNCTRL1, CM_PLAYBACK_SPDF); |
1211 | setup_ac3(cm, subs, 0, 0); | 1228 | setup_ac3(cm, subs, 0, 0); |
1212 | } | 1229 | } |
@@ -1226,7 +1243,7 @@ static int snd_cmipci_playback_prepare(struct snd_pcm_substream *substream) | |||
1226 | int rate = substream->runtime->rate; | 1243 | int rate = substream->runtime->rate; |
1227 | int err, do_spdif, do_ac3 = 0; | 1244 | int err, do_spdif, do_ac3 = 0; |
1228 | 1245 | ||
1229 | do_spdif = ((rate == 44100 || rate == 48000) && | 1246 | do_spdif = (rate >= 44100 && |
1230 | substream->runtime->format == SNDRV_PCM_FORMAT_S16_LE && | 1247 | substream->runtime->format == SNDRV_PCM_FORMAT_S16_LE && |
1231 | substream->runtime->channels == 2); | 1248 | substream->runtime->channels == 2); |
1232 | if (do_spdif && cm->can_ac3_hw) | 1249 | if (do_spdif && cm->can_ac3_hw) |
@@ -1514,6 +1531,11 @@ static int snd_cmipci_playback_open(struct snd_pcm_substream *substream) | |||
1514 | if ((err = open_device_check(cm, CM_OPEN_PLAYBACK, substream)) < 0) | 1531 | if ((err = open_device_check(cm, CM_OPEN_PLAYBACK, substream)) < 0) |
1515 | return err; | 1532 | return err; |
1516 | runtime->hw = snd_cmipci_playback; | 1533 | runtime->hw = snd_cmipci_playback; |
1534 | if (cm->chip_version == 68) { | ||
1535 | runtime->hw.rates |= SNDRV_PCM_RATE_88200 | | ||
1536 | SNDRV_PCM_RATE_96000; | ||
1537 | runtime->hw.rate_max = 96000; | ||
1538 | } | ||
1517 | snd_pcm_hw_constraint_minmax(runtime, SNDRV_PCM_HW_PARAM_BUFFER_SIZE, 0, 0x10000); | 1539 | snd_pcm_hw_constraint_minmax(runtime, SNDRV_PCM_HW_PARAM_BUFFER_SIZE, 0, 0x10000); |
1518 | cm->dig_pcm_status = cm->dig_status; | 1540 | cm->dig_pcm_status = cm->dig_status; |
1519 | return 0; | 1541 | return 0; |
@@ -1556,6 +1578,11 @@ static int snd_cmipci_playback2_open(struct snd_pcm_substream *substream) | |||
1556 | else if (cm->max_channels == 8) | 1578 | else if (cm->max_channels == 8) |
1557 | snd_pcm_hw_constraint_list(runtime, 0, SNDRV_PCM_HW_PARAM_CHANNELS, &hw_constraints_channels_8); | 1579 | snd_pcm_hw_constraint_list(runtime, 0, SNDRV_PCM_HW_PARAM_CHANNELS, &hw_constraints_channels_8); |
1558 | } | 1580 | } |
1581 | if (cm->chip_version == 68) { | ||
1582 | runtime->hw.rates |= SNDRV_PCM_RATE_88200 | | ||
1583 | SNDRV_PCM_RATE_96000; | ||
1584 | runtime->hw.rate_max = 96000; | ||
1585 | } | ||
1559 | snd_pcm_hw_constraint_minmax(runtime, SNDRV_PCM_HW_PARAM_BUFFER_SIZE, 0, 0x10000); | 1586 | snd_pcm_hw_constraint_minmax(runtime, SNDRV_PCM_HW_PARAM_BUFFER_SIZE, 0, 0x10000); |
1560 | } | 1587 | } |
1561 | mutex_unlock(&cm->open_mutex); | 1588 | mutex_unlock(&cm->open_mutex); |
@@ -1574,6 +1601,11 @@ static int snd_cmipci_playback_spdif_open(struct snd_pcm_substream *substream) | |||
1574 | runtime->hw = snd_cmipci_playback_spdif; | 1601 | runtime->hw = snd_cmipci_playback_spdif; |
1575 | if (cm->chip_version >= 37) | 1602 | if (cm->chip_version >= 37) |
1576 | runtime->hw.formats |= SNDRV_PCM_FMTBIT_S32_LE; | 1603 | runtime->hw.formats |= SNDRV_PCM_FMTBIT_S32_LE; |
1604 | if (cm->chip_version == 68) { | ||
1605 | runtime->hw.rates |= SNDRV_PCM_RATE_88200 | | ||
1606 | SNDRV_PCM_RATE_96000; | ||
1607 | runtime->hw.rate_max = 96000; | ||
1608 | } | ||
1577 | } else { | 1609 | } else { |
1578 | runtime->hw = snd_cmipci_playback_iec958_subframe; | 1610 | runtime->hw = snd_cmipci_playback_iec958_subframe; |
1579 | } | 1611 | } |