[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>
This commit is contained in:
parent
26be865923
commit
2d7eb7cb2b
|
@ -1211,16 +1211,18 @@ Prior to version 0.9.0rc4 options had a 'snd_' prefix. This was removed.
|
||||||
------------------
|
------------------
|
||||||
|
|
||||||
Module for AC'97 motherboards based on VIA 82C686A/686B, 8233,
|
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
|
mpu_port - 0x300,0x310,0x320,0x330, otherwise obtain BIOS setup
|
||||||
[VIA686A/686B only]
|
[VIA686A/686B only]
|
||||||
joystick - Enable joystick (default off) [VIA686A/686B only]
|
joystick - Enable joystick (default off) [VIA686A/686B only]
|
||||||
ac97_clock - AC'97 codec clock base (default 48000Hz)
|
ac97_clock - AC'97 codec clock base (default 48000Hz)
|
||||||
dxs_support - support DXS channels,
|
dxs_support - support DXS channels,
|
||||||
0 = auto (defalut), 1 = enable, 2 = disable,
|
0 = auto (default), 1 = enable, 2 = disable,
|
||||||
3 = 48k only, 4 = no VRA
|
3 = 48k only, 4 = no VRA, 5 = enable any sample
|
||||||
[VIA8233/C,8235 only]
|
rate and different sample rates on different
|
||||||
|
channels
|
||||||
|
[VIA8233/C, 8235, 8237 only]
|
||||||
ac97_quirk - AC'97 workaround for strange hardware
|
ac97_quirk - AC'97 workaround for strange hardware
|
||||||
See the description of intel8x0 module for details.
|
See the description of intel8x0 module for details.
|
||||||
|
|
||||||
|
@ -1232,18 +1234,21 @@ Prior to version 0.9.0rc4 options had a 'snd_' prefix. This was removed.
|
||||||
default value 1.4. Then the interrupt number will be
|
default value 1.4. Then the interrupt number will be
|
||||||
assigned under 15. You might also upgrade your BIOS.
|
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
|
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
|
As default (dxs_support = 0), 48k fixed rate is chosen
|
||||||
except for the known devices since the output is often
|
except for the known devices since the output is often
|
||||||
noisy except for 48k on some mother boards due to the
|
noisy except for 48k on some mother boards due to the
|
||||||
bug of BIOS.
|
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
|
sample rates (e.g. 44.1kHz of mp3 playback), please let us
|
||||||
know the PCI subsystem vendor/device id's (output of
|
know the PCI subsystem vendor/device id's (output of
|
||||||
"lspci -nv").
|
"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
|
work and the default setting is ok, dxs_support=3 is the
|
||||||
right choice. If the default setting doesn't work at all,
|
right choice. If the default setting doesn't work at all,
|
||||||
try dxs_support=2 to disable the DXS channels.
|
try dxs_support=2 to disable the DXS channels.
|
||||||
|
|
|
@ -101,7 +101,7 @@ MODULE_PARM_DESC(ac97_clock, "AC'97 codec clock (default 48000Hz).");
|
||||||
module_param_array(ac97_quirk, charp, NULL, 0444);
|
module_param_array(ac97_quirk, charp, NULL, 0444);
|
||||||
MODULE_PARM_DESC(ac97_quirk, "AC'97 workaround for strange hardware.");
|
MODULE_PARM_DESC(ac97_quirk, "AC'97 workaround for strange hardware.");
|
||||||
module_param_array(dxs_support, int, NULL, 0444);
|
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 */
|
/* pci ids */
|
||||||
|
@ -302,6 +302,7 @@ DEFINE_VIA_REGSET(CAPTURE_8233, 0x60);
|
||||||
#define VIA_DXS_DISABLE 2
|
#define VIA_DXS_DISABLE 2
|
||||||
#define VIA_DXS_48K 3
|
#define VIA_DXS_48K 3
|
||||||
#define VIA_DXS_NO_VRA 4
|
#define VIA_DXS_NO_VRA 4
|
||||||
|
#define VIA_DXS_SRC 5
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -380,6 +381,7 @@ struct _snd_via82xx {
|
||||||
struct via_rate_lock rates[2]; /* playback and capture */
|
struct via_rate_lock rates[2]; /* playback and capture */
|
||||||
unsigned int dxs_fixed: 1; /* DXS channel accepts only 48kHz */
|
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 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 */
|
unsigned int spdif_on: 1; /* only spdif rates work to external DACs */
|
||||||
|
|
||||||
snd_pcm_t *pcms[2];
|
snd_pcm_t *pcms[2];
|
||||||
|
@ -924,15 +926,16 @@ static int snd_via8233_playback_prepare(snd_pcm_substream_t *substream)
|
||||||
via82xx_t *chip = snd_pcm_substream_chip(substream);
|
via82xx_t *chip = snd_pcm_substream_chip(substream);
|
||||||
viadev_t *viadev = (viadev_t *)substream->runtime->private_data;
|
viadev_t *viadev = (viadev_t *)substream->runtime->private_data;
|
||||||
snd_pcm_runtime_t *runtime = substream->runtime;
|
snd_pcm_runtime_t *runtime = substream->runtime;
|
||||||
|
int ac97_rate = chip->dxs_src ? 48000 : runtime->rate;
|
||||||
int rate_changed;
|
int rate_changed;
|
||||||
u32 rbits;
|
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;
|
return rate_changed;
|
||||||
if (rate_changed) {
|
if (rate_changed) {
|
||||||
snd_ac97_set_rate(chip->ac97, AC97_PCM_FRONT_DAC_RATE,
|
snd_ac97_set_rate(chip->ac97, AC97_PCM_FRONT_DAC_RATE,
|
||||||
chip->no_vra ? 48000 : runtime->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)
|
if (runtime->rate == 48000)
|
||||||
rbits = 0xfffff;
|
rbits = 0xfffff;
|
||||||
|
@ -1074,6 +1077,12 @@ static int snd_via82xx_pcm_open(via82xx_t *chip, viadev_t *viadev, snd_pcm_subst
|
||||||
/* fixed DXS playback rate */
|
/* fixed DXS playback rate */
|
||||||
runtime->hw.rates = SNDRV_PCM_RATE_48000;
|
runtime->hw.rates = SNDRV_PCM_RATE_48000;
|
||||||
runtime->hw.rate_min = runtime->hw.rate_max = 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) {
|
} else if (! ratep->rate) {
|
||||||
int idx = viadev->direction ? AC97_RATES_ADC : AC97_RATES_FRONT_DAC;
|
int idx = viadev->direction ? AC97_RATES_ADC : AC97_RATES_FRONT_DAC;
|
||||||
runtime->hw.rates = chip->ac97->rates[idx];
|
runtime->hw.rates = chip->ac97->rates[idx];
|
||||||
|
@ -2149,6 +2158,7 @@ static int __devinit check_dxs_list(struct pci_dev *pci)
|
||||||
{ .vendor = 0x1043, .device = 0x8095, .action = VIA_DXS_NO_VRA }, /* ASUS A7V8X (FIXME: possibly VIA_DXS_ENABLE?)*/
|
{ .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 = 0x80a1, .action = VIA_DXS_NO_VRA }, /* ASUS A7V8-X */
|
||||||
{ .vendor = 0x1043, .device = 0x80b0, .action = VIA_DXS_NO_VRA }, /* ASUS A7V600 & K8V*/
|
{ .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 = 0x1071, .device = 0x8375, .action = VIA_DXS_NO_VRA }, /* Vobis/Yakumo/Mitac notebook */
|
||||||
{ .vendor = 0x10cf, .device = 0x118e, .action = VIA_DXS_ENABLE }, /* FSC laptop */
|
{ .vendor = 0x10cf, .device = 0x118e, .action = VIA_DXS_ENABLE }, /* FSC laptop */
|
||||||
{ .vendor = 0x1106, .device = 0x4161, .action = VIA_DXS_NO_VRA }, /* ASRock K7VT2 */
|
{ .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,
|
||||||
chip->dxs_fixed = 1;
|
chip->dxs_fixed = 1;
|
||||||
else if (dxs_support[dev] == VIA_DXS_NO_VRA)
|
else if (dxs_support[dev] == VIA_DXS_NO_VRA)
|
||||||
chip->no_vra = 1;
|
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)
|
if ((err = snd_via8233_init_misc(chip, dev)) < 0)
|
||||||
goto __error;
|
goto __error;
|
||||||
|
|
Loading…
Reference in New Issue