aboutsummaryrefslogtreecommitdiffstats
path: root/sound/pci/oxygen/oxygen_lib.c
diff options
context:
space:
mode:
authorClemens Ladisch <clemens@ladisch.de>2009-02-19 02:44:12 -0500
committerTakashi Iwai <tiwai@suse.de>2009-02-19 04:22:26 -0500
commit1275d6f608abda23d101ada17dc39940192d4bc4 (patch)
tree17a9954dc31d2fa79494fe9b9b867a48a1dafc3e /sound/pci/oxygen/oxygen_lib.c
parent30459d7b1843cbdea56ca120c8cac10dc5613e90 (diff)
sound: oxygen: automatically restore overwritten EEPROM
If the EEPROM was partially overwritten (which seems to happen before the OS is booted), restore its entire contents by deducing it from the remaining information. This does not have any effect on the Linux driver, which works even with incomplete information in the EEPROM, but it makes other drivers work again. Signed-off-by: Clemens Ladisch <clemens@ladisch.de> Signed-off-by: Takashi Iwai <tiwai@suse.de>
Diffstat (limited to 'sound/pci/oxygen/oxygen_lib.c')
-rw-r--r--sound/pci/oxygen/oxygen_lib.c29
1 files changed, 29 insertions, 0 deletions
diff --git a/sound/pci/oxygen/oxygen_lib.c b/sound/pci/oxygen/oxygen_lib.c
index d83c3a957323..6e1cdd2fd768 100644
--- a/sound/pci/oxygen/oxygen_lib.c
+++ b/sound/pci/oxygen/oxygen_lib.c
@@ -272,6 +272,34 @@ oxygen_search_pci_id(struct oxygen *chip, const struct pci_device_id ids[])
272 return NULL; 272 return NULL;
273} 273}
274 274
275static void oxygen_restore_eeprom(struct oxygen *chip,
276 const struct pci_device_id *id)
277{
278 if (oxygen_read_eeprom(chip, 0) != OXYGEN_EEPROM_ID) {
279 /*
280 * This function gets called only when a known card model has
281 * been detected, i.e., we know there is a valid subsystem
282 * product ID at index 2 in the EEPROM. Therefore, we have
283 * been able to deduce the correct subsystem vendor ID, and
284 * this is enough information to restore the original EEPROM
285 * contents.
286 */
287 oxygen_write_eeprom(chip, 1, id->subvendor);
288 oxygen_write_eeprom(chip, 0, OXYGEN_EEPROM_ID);
289
290 oxygen_set_bits8(chip, OXYGEN_MISC,
291 OXYGEN_MISC_WRITE_PCI_SUBID);
292 pci_write_config_word(chip->pci, PCI_SUBSYSTEM_VENDOR_ID,
293 id->subvendor);
294 pci_write_config_word(chip->pci, PCI_SUBSYSTEM_ID,
295 id->subdevice);
296 oxygen_clear_bits8(chip, OXYGEN_MISC,
297 OXYGEN_MISC_WRITE_PCI_SUBID);
298
299 snd_printk(KERN_INFO "EEPROM ID restored\n");
300 }
301}
302
275static void oxygen_init(struct oxygen *chip) 303static void oxygen_init(struct oxygen *chip)
276{ 304{
277 unsigned int i; 305 unsigned int i;
@@ -532,6 +560,7 @@ int oxygen_pci_probe(struct pci_dev *pci, int index, char *id,
532 err = -ENODEV; 560 err = -ENODEV;
533 goto err_pci_regions; 561 goto err_pci_regions;
534 } 562 }
563 oxygen_restore_eeprom(chip, pci_id);
535 err = get_model(chip, pci_id); 564 err = get_model(chip, pci_id);
536 if (err < 0) 565 if (err < 0)
537 goto err_pci_regions; 566 goto err_pci_regions;