diff options
author | Sergey Vlasov <vsu@altlinux.ru> | 2005-04-11 09:04:33 -0400 |
---|---|---|
committer | Jaroslav Kysela <perex@suse.cz> | 2005-05-29 04:00:24 -0400 |
commit | 2d7eb7cb2bab1fbe8cfb610277b19ad40a9f7c75 (patch) | |
tree | 02ed97111c92b32d4aa4944b97de6d7bb88703de /sound/pci/via82xx.c | |
parent | 26be865923ce9edefe8ddc007ddb1c098c29c449 (diff) |
[ALSA] Support all sample rate conversion capabilities of DXS channels
Documentation,VIA82xx driver
Add support for full sample rate conversion capabilities of DXS
channels present in VIA VT8233/5/7 controllers:
- any sample rate in the 8000 ... 48000 Hz range is supported even if
the AC'97 codec supports only 48000 Hz output;
- different DXS channels can use different sample rates at the same
time (the controller performs required sample rate conversion and
mixing in hardware).
Signed-off-by: Sergey Vlasov <vsu@altlinux.ru>
Signed-off-by: Takashi Iwai <tiwai@suse.de>
Diffstat (limited to 'sound/pci/via82xx.c')
-rw-r--r-- | sound/pci/via82xx.c | 20 |
1 files changed, 17 insertions, 3 deletions
diff --git a/sound/pci/via82xx.c b/sound/pci/via82xx.c index 9b4d74d49f98..2f1e6ebd56a7 100644 --- a/sound/pci/via82xx.c +++ b/sound/pci/via82xx.c | |||
@@ -101,7 +101,7 @@ MODULE_PARM_DESC(ac97_clock, "AC'97 codec clock (default 48000Hz)."); | |||
101 | module_param_array(ac97_quirk, charp, NULL, 0444); | 101 | module_param_array(ac97_quirk, charp, NULL, 0444); |
102 | MODULE_PARM_DESC(ac97_quirk, "AC'97 workaround for strange hardware."); | 102 | MODULE_PARM_DESC(ac97_quirk, "AC'97 workaround for strange hardware."); |
103 | module_param_array(dxs_support, int, NULL, 0444); | 103 | module_param_array(dxs_support, int, NULL, 0444); |
104 | MODULE_PARM_DESC(dxs_support, "Support for DXS channels (0 = auto, 1 = enable, 2 = disable, 3 = 48k only, 4 = no VRA)"); | 104 | MODULE_PARM_DESC(dxs_support, "Support for DXS channels (0 = auto, 1 = enable, 2 = disable, 3 = 48k only, 4 = no VRA, 5 = enable any sample rate)"); |
105 | 105 | ||
106 | 106 | ||
107 | /* pci ids */ | 107 | /* pci ids */ |
@@ -302,6 +302,7 @@ DEFINE_VIA_REGSET(CAPTURE_8233, 0x60); | |||
302 | #define VIA_DXS_DISABLE 2 | 302 | #define VIA_DXS_DISABLE 2 |
303 | #define VIA_DXS_48K 3 | 303 | #define VIA_DXS_48K 3 |
304 | #define VIA_DXS_NO_VRA 4 | 304 | #define VIA_DXS_NO_VRA 4 |
305 | #define VIA_DXS_SRC 5 | ||
305 | 306 | ||
306 | 307 | ||
307 | /* | 308 | /* |
@@ -380,6 +381,7 @@ struct _snd_via82xx { | |||
380 | struct via_rate_lock rates[2]; /* playback and capture */ | 381 | struct via_rate_lock rates[2]; /* playback and capture */ |
381 | unsigned int dxs_fixed: 1; /* DXS channel accepts only 48kHz */ | 382 | unsigned int dxs_fixed: 1; /* DXS channel accepts only 48kHz */ |
382 | unsigned int no_vra: 1; /* no need to set VRA on DXS channels */ | 383 | unsigned int no_vra: 1; /* no need to set VRA on DXS channels */ |
384 | unsigned int dxs_src: 1; /* use full SRC capabilities of DXS */ | ||
383 | unsigned int spdif_on: 1; /* only spdif rates work to external DACs */ | 385 | unsigned int spdif_on: 1; /* only spdif rates work to external DACs */ |
384 | 386 | ||
385 | snd_pcm_t *pcms[2]; | 387 | snd_pcm_t *pcms[2]; |
@@ -924,15 +926,16 @@ static int snd_via8233_playback_prepare(snd_pcm_substream_t *substream) | |||
924 | via82xx_t *chip = snd_pcm_substream_chip(substream); | 926 | via82xx_t *chip = snd_pcm_substream_chip(substream); |
925 | viadev_t *viadev = (viadev_t *)substream->runtime->private_data; | 927 | viadev_t *viadev = (viadev_t *)substream->runtime->private_data; |
926 | snd_pcm_runtime_t *runtime = substream->runtime; | 928 | snd_pcm_runtime_t *runtime = substream->runtime; |
929 | int ac97_rate = chip->dxs_src ? 48000 : runtime->rate; | ||
927 | int rate_changed; | 930 | int rate_changed; |
928 | u32 rbits; | 931 | u32 rbits; |
929 | 932 | ||
930 | if ((rate_changed = via_lock_rate(&chip->rates[0], runtime->rate)) < 0) | 933 | if ((rate_changed = via_lock_rate(&chip->rates[0], ac97_rate)) < 0) |
931 | return rate_changed; | 934 | return rate_changed; |
932 | if (rate_changed) { | 935 | if (rate_changed) { |
933 | snd_ac97_set_rate(chip->ac97, AC97_PCM_FRONT_DAC_RATE, | 936 | snd_ac97_set_rate(chip->ac97, AC97_PCM_FRONT_DAC_RATE, |
934 | chip->no_vra ? 48000 : runtime->rate); | 937 | chip->no_vra ? 48000 : runtime->rate); |
935 | snd_ac97_set_rate(chip->ac97, AC97_SPDIF, runtime->rate); | 938 | snd_ac97_set_rate(chip->ac97, AC97_SPDIF, ac97_rate); |
936 | } | 939 | } |
937 | if (runtime->rate == 48000) | 940 | if (runtime->rate == 48000) |
938 | rbits = 0xfffff; | 941 | rbits = 0xfffff; |
@@ -1074,6 +1077,12 @@ static int snd_via82xx_pcm_open(via82xx_t *chip, viadev_t *viadev, snd_pcm_subst | |||
1074 | /* fixed DXS playback rate */ | 1077 | /* fixed DXS playback rate */ |
1075 | runtime->hw.rates = SNDRV_PCM_RATE_48000; | 1078 | runtime->hw.rates = SNDRV_PCM_RATE_48000; |
1076 | runtime->hw.rate_min = runtime->hw.rate_max = 48000; | 1079 | runtime->hw.rate_min = runtime->hw.rate_max = 48000; |
1080 | } else if (chip->dxs_src && viadev->reg_offset < 0x40) { | ||
1081 | /* use full SRC capabilities of DXS */ | ||
1082 | runtime->hw.rates = (SNDRV_PCM_RATE_CONTINUOUS | | ||
1083 | SNDRV_PCM_RATE_8000_48000); | ||
1084 | runtime->hw.rate_min = 8000; | ||
1085 | runtime->hw.rate_max = 48000; | ||
1077 | } else if (! ratep->rate) { | 1086 | } else if (! ratep->rate) { |
1078 | int idx = viadev->direction ? AC97_RATES_ADC : AC97_RATES_FRONT_DAC; | 1087 | int idx = viadev->direction ? AC97_RATES_ADC : AC97_RATES_FRONT_DAC; |
1079 | runtime->hw.rates = chip->ac97->rates[idx]; | 1088 | runtime->hw.rates = chip->ac97->rates[idx]; |
@@ -2149,6 +2158,7 @@ static int __devinit check_dxs_list(struct pci_dev *pci) | |||
2149 | { .vendor = 0x1043, .device = 0x8095, .action = VIA_DXS_NO_VRA }, /* ASUS A7V8X (FIXME: possibly VIA_DXS_ENABLE?)*/ | 2158 | { .vendor = 0x1043, .device = 0x8095, .action = VIA_DXS_NO_VRA }, /* ASUS A7V8X (FIXME: possibly VIA_DXS_ENABLE?)*/ |
2150 | { .vendor = 0x1043, .device = 0x80a1, .action = VIA_DXS_NO_VRA }, /* ASUS A7V8-X */ | 2159 | { .vendor = 0x1043, .device = 0x80a1, .action = VIA_DXS_NO_VRA }, /* ASUS A7V8-X */ |
2151 | { .vendor = 0x1043, .device = 0x80b0, .action = VIA_DXS_NO_VRA }, /* ASUS A7V600 & K8V*/ | 2160 | { .vendor = 0x1043, .device = 0x80b0, .action = VIA_DXS_NO_VRA }, /* ASUS A7V600 & K8V*/ |
2161 | { .vendor = 0x1043, .device = 0x812a, .action = VIA_DXS_SRC }, /* ASUS A8V Deluxe */ | ||
2152 | { .vendor = 0x1071, .device = 0x8375, .action = VIA_DXS_NO_VRA }, /* Vobis/Yakumo/Mitac notebook */ | 2162 | { .vendor = 0x1071, .device = 0x8375, .action = VIA_DXS_NO_VRA }, /* Vobis/Yakumo/Mitac notebook */ |
2153 | { .vendor = 0x10cf, .device = 0x118e, .action = VIA_DXS_ENABLE }, /* FSC laptop */ | 2163 | { .vendor = 0x10cf, .device = 0x118e, .action = VIA_DXS_ENABLE }, /* FSC laptop */ |
2154 | { .vendor = 0x1106, .device = 0x4161, .action = VIA_DXS_NO_VRA }, /* ASRock K7VT2 */ | 2164 | { .vendor = 0x1106, .device = 0x4161, .action = VIA_DXS_NO_VRA }, /* ASRock K7VT2 */ |
@@ -2288,6 +2298,10 @@ static int __devinit snd_via82xx_probe(struct pci_dev *pci, | |||
2288 | chip->dxs_fixed = 1; | 2298 | chip->dxs_fixed = 1; |
2289 | else if (dxs_support[dev] == VIA_DXS_NO_VRA) | 2299 | else if (dxs_support[dev] == VIA_DXS_NO_VRA) |
2290 | chip->no_vra = 1; | 2300 | chip->no_vra = 1; |
2301 | else if (dxs_support[dev] == VIA_DXS_SRC) { | ||
2302 | chip->no_vra = 1; | ||
2303 | chip->dxs_src = 1; | ||
2304 | } | ||
2291 | } | 2305 | } |
2292 | if ((err = snd_via8233_init_misc(chip, dev)) < 0) | 2306 | if ((err = snd_via8233_init_misc(chip, dev)) < 0) |
2293 | goto __error; | 2307 | goto __error; |