aboutsummaryrefslogtreecommitdiffstats
path: root/sound/pci/oxygen
diff options
context:
space:
mode:
authorClemens Ladisch <clemens@ladisch.de>2010-10-06 04:57:50 -0400
committerTakashi Iwai <tiwai@suse.de>2010-10-06 10:27:12 -0400
commit7cb4ced5aa83b681c76b004c8960b4f2a6471fef (patch)
tree8bb82ad7fa977c20470aedff6ed84d875713e3a5 /sound/pci/oxygen
parent93943beb29be7084afb61556e96bc454079bfb0e (diff)
ALSA: oxygen: rewrite PCIe bridge initialization
Change the PCIe/PCI bridge initialization code to configure only the bridge that is actually connected to the sound chip, instead of any bridge found in the system. The new code also makes it easier to add other bridges. 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.c40
1 files changed, 23 insertions, 17 deletions
diff --git a/sound/pci/oxygen/oxygen_lib.c b/sound/pci/oxygen/oxygen_lib.c
index 7e93cf884437..d10cc6ee1a68 100644
--- a/sound/pci/oxygen/oxygen_lib.c
+++ b/sound/pci/oxygen/oxygen_lib.c
@@ -308,25 +308,31 @@ static void oxygen_restore_eeprom(struct oxygen *chip,
308 } 308 }
309} 309}
310 310
311static void pci_bridge_magic(void) 311static void configure_pcie_bridge(struct pci_dev *pci)
312{ 312{
313 struct pci_dev *pci = NULL; 313 enum { PI7C9X110 };
314 static const struct pci_device_id bridge_ids[] = {
315 { PCI_DEVICE(0x12d8, 0xe110), .driver_data = PI7C9X110 },
316 { }
317 };
318 struct pci_dev *bridge;
319 const struct pci_device_id *id;
314 u32 tmp; 320 u32 tmp;
315 321
316 for (;;) { 322 if (!pci->bus || !pci->bus->self)
317 /* If there is any Pericom PI7C9X110 PCI-E/PCI bridge ... */ 323 return;
318 pci = pci_get_device(0x12d8, 0xe110, pci); 324 bridge = pci->bus->self;
319 if (!pci) 325
320 break; 326 id = pci_match_id(bridge_ids, bridge);
321 /* 327 if (!id)
322 * ... configure its secondary internal arbiter to park to 328 return;
323 * the secondary port, instead of to the last master. 329
324 */ 330 switch (id->driver_data) {
325 if (!pci_read_config_dword(pci, 0x40, &tmp)) { 331 case PI7C9X110: /* Pericom PI7C9X110 PCIe/PCI bridge */
326 tmp |= 1; 332 pci_read_config_dword(bridge, 0x40, &tmp);
327 pci_write_config_dword(pci, 0x40, tmp); 333 tmp |= 1; /* park the PCI arbiter to the sound chip */
328 } 334 pci_write_config_dword(bridge, 0x40, tmp);
329 /* Why? Try asking C-Media. */ 335 break;
330 } 336 }
331} 337}
332 338
@@ -613,7 +619,7 @@ int oxygen_pci_probe(struct pci_dev *pci, int index, char *id,
613 snd_card_set_dev(card, &pci->dev); 619 snd_card_set_dev(card, &pci->dev);
614 card->private_free = oxygen_card_free; 620 card->private_free = oxygen_card_free;
615 621
616 pci_bridge_magic(); 622 configure_pcie_bridge(pci);
617 oxygen_init(chip); 623 oxygen_init(chip);
618 chip->model.init(chip); 624 chip->model.init(chip);
619 625