summaryrefslogtreecommitdiffstats
path: root/sound/pci/oxygen
diff options
context:
space:
mode:
authorClemens Ladisch <clemens@ladisch.de>2009-09-28 11:05:58 +0200
committerTakashi Iwai <tiwai@suse.de>2009-09-28 11:53:30 +0200
commit362bc24d6746bcd49bb4853fc5aa7d4c728b3f9e (patch)
treeb9687fdf6129d3e6896ccc693c8065f31e032245 /sound/pci/oxygen
parent87b61902ce3dec23a2d8256b9cfcf4e28786a320 (diff)
downloadlinux-362bc24d6746bcd49bb4853fc5aa7d4c728b3f9e.tar.bz2
sound: oxygen: fix for PI7C9X110 compatibility
If the card is used with a Pericom PI7C9X110 PCI-E/PCI bridge, reconfigure the latter's PCI buffering to fix an unknown problem. Signed-off-by: Clemens Ladisch <clemens@ladisch.de> Signed-off-by: Takashi Iwai <tiwai@suse.de>
Diffstat (limited to 'sound/pci/oxygen')
-rw-r--r--sound/pci/oxygen/oxygen_lib.c23
1 files changed, 23 insertions, 0 deletions
diff --git a/sound/pci/oxygen/oxygen_lib.c b/sound/pci/oxygen/oxygen_lib.c
index c9f271419eb8..9c5e6450eebb 100644
--- a/sound/pci/oxygen/oxygen_lib.c
+++ b/sound/pci/oxygen/oxygen_lib.c
@@ -307,6 +307,28 @@ static void oxygen_restore_eeprom(struct oxygen *chip,
}
}
+static void pci_bridge_magic(void)
+{
+ struct pci_dev *pci = NULL;
+ u32 tmp;
+
+ for (;;) {
+ /* If there is any Pericom PI7C9X110 PCI-E/PCI bridge ... */
+ pci = pci_get_device(0x12d8, 0xe110, pci);
+ if (!pci)
+ break;
+ /*
+ * ... configure its secondary internal arbiter to park to
+ * the secondary port, instead of to the last master.
+ */
+ if (!pci_read_config_dword(pci, 0x40, &tmp)) {
+ tmp |= 1;
+ pci_write_config_dword(pci, 0x40, tmp);
+ }
+ /* Why? Try asking C-Media. */
+ }
+}
+
static void oxygen_init(struct oxygen *chip)
{
unsigned int i;
@@ -585,6 +607,7 @@ int oxygen_pci_probe(struct pci_dev *pci, int index, char *id,
snd_card_set_dev(card, &pci->dev);
card->private_free = oxygen_card_free;
+ pci_bridge_magic();
oxygen_init(chip);
chip->model.init(chip);