summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTobin Davis <tdavis@dsl-only.net>2008-01-15 11:23:55 +0100
committerJaroslav Kysela <perex@perex.cz>2008-01-31 17:29:58 +0100
commitbcd7200394bde40e3735054fc660b6f5012638b3 (patch)
tree2fce8f3b086f8de06ae244c5c5026c50d4fe7cd1
parentfb920b7d8b65f253671073d40d490d0968151680 (diff)
[ALSA] HDA: Enable chipset gcap usage
This patch removes hardcoded values for the number of streams supported by the southbridge in most chipsets, and reads these values from the chipset directly. Most systems are hardwired for 4 streams in each direction, but newer chipsets change that capability. Signed-off-by: Tobin Davis <tdavis@dsl-only.net> Signed-off-by: Takashi Iwai <tiwai@suse.de> Signed-off-by: Jaroslav Kysela <perex@perex.cz>
-rw-r--r--sound/pci/hda/hda_intel.c56
1 files changed, 36 insertions, 20 deletions
diff --git a/sound/pci/hda/hda_intel.c b/sound/pci/hda/hda_intel.c
index 25f35fa9706..5f2c3ca863d 100644
--- a/sound/pci/hda/hda_intel.c
+++ b/sound/pci/hda/hda_intel.c
@@ -1708,12 +1708,13 @@ static int __devinit azx_create(struct snd_card *card, struct pci_dev *pci,
{
struct azx *chip;
int err;
+ unsigned short gcap;
static struct snd_device_ops ops = {
.dev_free = azx_dev_free,
};
*rchip = NULL;
-
+
err = pci_enable_device(pci);
if (err < 0)
return err;
@@ -1775,25 +1776,40 @@ static int __devinit azx_create(struct snd_card *card, struct pci_dev *pci,
pci_set_master(pci);
synchronize_irq(chip->irq);
- switch (chip->driver_type) {
- case AZX_DRIVER_ULI:
- chip->playback_streams = ULI_NUM_PLAYBACK;
- chip->capture_streams = ULI_NUM_CAPTURE;
- chip->playback_index_offset = ULI_PLAYBACK_INDEX;
- chip->capture_index_offset = ULI_CAPTURE_INDEX;
- break;
- case AZX_DRIVER_ATIHDMI:
- chip->playback_streams = ATIHDMI_NUM_PLAYBACK;
- chip->capture_streams = ATIHDMI_NUM_CAPTURE;
- chip->playback_index_offset = ATIHDMI_PLAYBACK_INDEX;
- chip->capture_index_offset = ATIHDMI_CAPTURE_INDEX;
- break;
- default:
- chip->playback_streams = ICH6_NUM_PLAYBACK;
- chip->capture_streams = ICH6_NUM_CAPTURE;
- chip->playback_index_offset = ICH6_PLAYBACK_INDEX;
- chip->capture_index_offset = ICH6_CAPTURE_INDEX;
- break;
+ gcap = azx_readw(chip, GCAP);
+ snd_printdd("chipset global capabilities = 0x%x\n", gcap);
+
+ if (gcap) {
+ /* read number of streams from GCAP register instead of using
+ * hardcoded value
+ */
+ chip->playback_streams = (gcap & (0xF << 12)) >> 12;
+ chip->capture_streams = (gcap & (0xF << 8)) >> 8;
+ chip->playback_index_offset = (gcap & (0xF << 12)) >> 12;
+ chip->capture_index_offset = 0;
+ } else {
+ /* gcap didn't give any info, switching to old method */
+
+ switch (chip->driver_type) {
+ case AZX_DRIVER_ULI:
+ chip->playback_streams = ULI_NUM_PLAYBACK;
+ chip->capture_streams = ULI_NUM_CAPTURE;
+ chip->playback_index_offset = ULI_PLAYBACK_INDEX;
+ chip->capture_index_offset = ULI_CAPTURE_INDEX;
+ break;
+ case AZX_DRIVER_ATIHDMI:
+ chip->playback_streams = ATIHDMI_NUM_PLAYBACK;
+ chip->capture_streams = ATIHDMI_NUM_CAPTURE;
+ chip->playback_index_offset = ATIHDMI_PLAYBACK_INDEX;
+ chip->capture_index_offset = ATIHDMI_CAPTURE_INDEX;
+ break;
+ default:
+ chip->playback_streams = ICH6_NUM_PLAYBACK;
+ chip->capture_streams = ICH6_NUM_CAPTURE;
+ chip->playback_index_offset = ICH6_PLAYBACK_INDEX;
+ chip->capture_index_offset = ICH6_CAPTURE_INDEX;
+ break;
+ }
}
chip->num_streams = chip->playback_streams + chip->capture_streams;
chip->azx_dev = kcalloc(chip->num_streams, sizeof(*chip->azx_dev),