--------------------- PatchSet 3111 Date: 2005/04/11 15:04:33 Author: tiwai Branch: HEAD Tag: (none) Log: Summary: Support all sample rate conversion capabilities of DXS channels 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 Members: Documentation/ALSA-Configuration.txt:1.69->1.70 pci/via82xx.c:1.141->1.142 Index: /Documentation/sound/alsa/ALSA-Configuration.txt diff -u /Documentation/sound/alsa/ALSA-Configuration.txt.old /Documentation/sound/alsa/ALSA-Configuration.txt --- /Documentation/sound/alsa/ALSA-Configuration.txt.old Mon Feb 7 00:40:37 2005 +++ /Documentation/sound/alsa/ALSA-Configuration.txt Mon Apr 11 07:04:33 2005 @@ -1211,16 +1211,18 @@ ------------------ Module for AC'97 motherboards based on VIA 82C686A/686B, 8233, - 8233A, 8233C, 8235 (south) bridge. + 8233A, 8233C, 8235, 8237 (south) bridge. mpu_port - 0x300,0x310,0x320,0x330, otherwise obtain BIOS setup [VIA686A/686B only] joystick - Enable joystick (default off) [VIA686A/686B only] ac97_clock - AC'97 codec clock base (default 48000Hz) dxs_support - support DXS channels, - 0 = auto (defalut), 1 = enable, 2 = disable, - 3 = 48k only, 4 = no VRA - [VIA8233/C,8235 only] + 0 = auto (default), 1 = enable, 2 = disable, + 3 = 48k only, 4 = no VRA, 5 = enable any sample + rate and different sample rates on different + channels + [VIA8233/C, 8235, 8237 only] ac97_quirk - AC'97 workaround for strange hardware See the description of intel8x0 module for details. @@ -1232,18 +1234,21 @@ default value 1.4. Then the interrupt number will be assigned under 15. You might also upgrade your BIOS. - Note: VIA8233/5 (not VIA8233A) can support DXS (direct sound) + Note: VIA8233/5/7 (not VIA8233A) can support DXS (direct sound) channels as the first PCM. On these channels, up to 4 - streams can be played at the same time. + streams can be played at the same time, and the controller + can perform sample rate conversion with separate rates for + each channel. As default (dxs_support = 0), 48k fixed rate is chosen except for the known devices since the output is often noisy except for 48k on some mother boards due to the bug of BIOS. - Please try once dxs_support=1 and if it works on other + Please try once dxs_support=5 and if it works on other sample rates (e.g. 44.1kHz of mp3 playback), please let us know the PCI subsystem vendor/device id's (output of "lspci -nv"). - If it doesn't work, try dxs_support=4. If it still doesn't + If dxs_support=5 does not work, try dxs_support=1; if it + doesn't work too, try dxs_support=4. If it still doesn't work and the default setting is ok, dxs_support=3 is the right choice. If the default setting doesn't work at all, try dxs_support=2 to disable the DXS channels. Index: /sound/pci/via82xx.c diff -u /sound/pci/via82xx.c.old /sound/pci/via82xx.c --- /sound/pci/via82xx.c.old Tue Mar 22 10:09:36 2005 +++ /sound/pci/via82xx.c Mon Apr 11 07:04:35 2005 @@ -101,7 +101,7 @@ module_param_array(ac97_quirk, charp, NULL, 0444); MODULE_PARM_DESC(ac97_quirk, "AC'97 workaround for strange hardware."); module_param_array(dxs_support, int, NULL, 0444); -MODULE_PARM_DESC(dxs_support, "Support for DXS channels (0 = auto, 1 = enable, 2 = disable, 3 = 48k only, 4 = no VRA)"); +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)"); /* pci ids */ @@ -302,6 +302,7 @@ #define VIA_DXS_DISABLE 2 #define VIA_DXS_48K 3 #define VIA_DXS_NO_VRA 4 +#define VIA_DXS_SRC 5 /* @@ -380,6 +381,7 @@ struct via_rate_lock rates[2]; /* playback and capture */ unsigned int dxs_fixed: 1; /* DXS channel accepts only 48kHz */ unsigned int no_vra: 1; /* no need to set VRA on DXS channels */ + unsigned int dxs_src: 1; /* use full SRC capabilities of DXS */ unsigned int spdif_on: 1; /* only spdif rates work to external DACs */ snd_pcm_t *pcms[2]; @@ -924,15 +926,16 @@ via82xx_t *chip = snd_pcm_substream_chip(substream); viadev_t *viadev = (viadev_t *)substream->runtime->private_data; snd_pcm_runtime_t *runtime = substream->runtime; + int ac97_rate = chip->dxs_src ? 48000 : runtime->rate; int rate_changed; u32 rbits; - if ((rate_changed = via_lock_rate(&chip->rates[0], runtime->rate)) < 0) + if ((rate_changed = via_lock_rate(&chip->rates[0], ac97_rate)) < 0) return rate_changed; if (rate_changed) { snd_ac97_set_rate(chip->ac97, AC97_PCM_FRONT_DAC_RATE, chip->no_vra ? 48000 : runtime->rate); - snd_ac97_set_rate(chip->ac97, AC97_SPDIF, runtime->rate); + snd_ac97_set_rate(chip->ac97, AC97_SPDIF, ac97_rate); } if (runtime->rate == 48000) rbits = 0xfffff; @@ -1074,6 +1077,12 @@ /* fixed DXS playback rate */ runtime->hw.rates = SNDRV_PCM_RATE_48000; runtime->hw.rate_min = runtime->hw.rate_max = 48000; + } else if (chip->dxs_src && viadev->reg_offset < 0x40) { + /* use full SRC capabilities of DXS */ + runtime->hw.rates = (SNDRV_PCM_RATE_CONTINUOUS | + SNDRV_PCM_RATE_8000_48000); + runtime->hw.rate_min = 8000; + runtime->hw.rate_max = 48000; } else if (! ratep->rate) { int idx = viadev->direction ? AC97_RATES_ADC : AC97_RATES_FRONT_DAC; runtime->hw.rates = chip->ac97->rates[idx]; @@ -2149,6 +2158,7 @@ { .vendor = 0x1043, .device = 0x8095, .action = VIA_DXS_NO_VRA }, /* ASUS A7V8X (FIXME: possibly VIA_DXS_ENABLE?)*/ { .vendor = 0x1043, .device = 0x80a1, .action = VIA_DXS_NO_VRA }, /* ASUS A7V8-X */ { .vendor = 0x1043, .device = 0x80b0, .action = VIA_DXS_NO_VRA }, /* ASUS A7V600 & K8V*/ + { .vendor = 0x1043, .device = 0x812a, .action = VIA_DXS_SRC }, /* ASUS A8V Deluxe */ { .vendor = 0x1071, .device = 0x8375, .action = VIA_DXS_NO_VRA }, /* Vobis/Yakumo/Mitac notebook */ { .vendor = 0x10cf, .device = 0x118e, .action = VIA_DXS_ENABLE }, /* FSC laptop */ { .vendor = 0x1106, .device = 0x4161, .action = VIA_DXS_NO_VRA }, /* ASRock K7VT2 */ @@ -2288,6 +2298,10 @@ chip->dxs_fixed = 1; else if (dxs_support[dev] == VIA_DXS_NO_VRA) chip->no_vra = 1; + else if (dxs_support[dev] == VIA_DXS_SRC) { + chip->no_vra = 1; + chip->dxs_src = 1; + } } if ((err = snd_via8233_init_misc(chip, dev)) < 0) goto __error;