diff options
Diffstat (limited to 'sound/pci/oxygen/oxygen_lib.c')
-rw-r--r-- | sound/pci/oxygen/oxygen_lib.c | 51 |
1 files changed, 43 insertions, 8 deletions
diff --git a/sound/pci/oxygen/oxygen_lib.c b/sound/pci/oxygen/oxygen_lib.c index 516d94ad2bbb..d83c3a957323 100644 --- a/sound/pci/oxygen/oxygen_lib.c +++ b/sound/pci/oxygen/oxygen_lib.c | |||
@@ -244,6 +244,34 @@ static void oxygen_proc_init(struct oxygen *chip) | |||
244 | #define oxygen_proc_init(chip) | 244 | #define oxygen_proc_init(chip) |
245 | #endif | 245 | #endif |
246 | 246 | ||
247 | static const struct pci_device_id * | ||
248 | oxygen_search_pci_id(struct oxygen *chip, const struct pci_device_id ids[]) | ||
249 | { | ||
250 | u16 subdevice; | ||
251 | |||
252 | /* | ||
253 | * Make sure the EEPROM pins are available, i.e., not used for SPI. | ||
254 | * (This function is called before we initialize or use SPI.) | ||
255 | */ | ||
256 | oxygen_clear_bits8(chip, OXYGEN_FUNCTION, | ||
257 | OXYGEN_FUNCTION_ENABLE_SPI_4_5); | ||
258 | /* | ||
259 | * Read the subsystem device ID directly from the EEPROM, because the | ||
260 | * chip didn't if the first EEPROM word was overwritten. | ||
261 | */ | ||
262 | subdevice = oxygen_read_eeprom(chip, 2); | ||
263 | /* | ||
264 | * We use only the subsystem device ID for searching because it is | ||
265 | * unique even without the subsystem vendor ID, which may have been | ||
266 | * overwritten in the EEPROM. | ||
267 | */ | ||
268 | for (; ids->vendor; ++ids) | ||
269 | if (ids->subdevice == subdevice && | ||
270 | ids->driver_data != BROKEN_EEPROM_DRIVER_DATA) | ||
271 | return ids; | ||
272 | return NULL; | ||
273 | } | ||
274 | |||
247 | static void oxygen_init(struct oxygen *chip) | 275 | static void oxygen_init(struct oxygen *chip) |
248 | { | 276 | { |
249 | unsigned int i; | 277 | unsigned int i; |
@@ -455,11 +483,15 @@ static void oxygen_card_free(struct snd_card *card) | |||
455 | 483 | ||
456 | int oxygen_pci_probe(struct pci_dev *pci, int index, char *id, | 484 | int oxygen_pci_probe(struct pci_dev *pci, int index, char *id, |
457 | struct module *owner, | 485 | struct module *owner, |
458 | const struct oxygen_model *model, | 486 | const struct pci_device_id *ids, |
459 | unsigned long driver_data) | 487 | int (*get_model)(struct oxygen *chip, |
488 | const struct pci_device_id *id | ||
489 | ) | ||
490 | ) | ||
460 | { | 491 | { |
461 | struct snd_card *card; | 492 | struct snd_card *card; |
462 | struct oxygen *chip; | 493 | struct oxygen *chip; |
494 | const struct pci_device_id *pci_id; | ||
463 | int err; | 495 | int err; |
464 | 496 | ||
465 | err = snd_card_create(index, id, owner, sizeof(*chip), &card); | 497 | err = snd_card_create(index, id, owner, sizeof(*chip), &card); |
@@ -470,7 +502,6 @@ int oxygen_pci_probe(struct pci_dev *pci, int index, char *id, | |||
470 | chip->card = card; | 502 | chip->card = card; |
471 | chip->pci = pci; | 503 | chip->pci = pci; |
472 | chip->irq = -1; | 504 | chip->irq = -1; |
473 | chip->model = *model; | ||
474 | spin_lock_init(&chip->reg_lock); | 505 | spin_lock_init(&chip->reg_lock); |
475 | mutex_init(&chip->mutex); | 506 | mutex_init(&chip->mutex); |
476 | INIT_WORK(&chip->spdif_input_bits_work, | 507 | INIT_WORK(&chip->spdif_input_bits_work, |
@@ -496,6 +527,15 @@ int oxygen_pci_probe(struct pci_dev *pci, int index, char *id, | |||
496 | } | 527 | } |
497 | chip->addr = pci_resource_start(pci, 0); | 528 | chip->addr = pci_resource_start(pci, 0); |
498 | 529 | ||
530 | pci_id = oxygen_search_pci_id(chip, ids); | ||
531 | if (!pci_id) { | ||
532 | err = -ENODEV; | ||
533 | goto err_pci_regions; | ||
534 | } | ||
535 | err = get_model(chip, pci_id); | ||
536 | if (err < 0) | ||
537 | goto err_pci_regions; | ||
538 | |||
499 | if (chip->model.model_data_size) { | 539 | if (chip->model.model_data_size) { |
500 | chip->model_data = kmalloc(chip->model.model_data_size, | 540 | chip->model_data = kmalloc(chip->model.model_data_size, |
501 | GFP_KERNEL); | 541 | GFP_KERNEL); |
@@ -509,11 +549,6 @@ int oxygen_pci_probe(struct pci_dev *pci, int index, char *id, | |||
509 | snd_card_set_dev(card, &pci->dev); | 549 | snd_card_set_dev(card, &pci->dev); |
510 | card->private_free = oxygen_card_free; | 550 | card->private_free = oxygen_card_free; |
511 | 551 | ||
512 | if (chip->model.probe) { | ||
513 | err = chip->model.probe(chip, driver_data); | ||
514 | if (err < 0) | ||
515 | goto err_card; | ||
516 | } | ||
517 | oxygen_init(chip); | 552 | oxygen_init(chip); |
518 | chip->model.init(chip); | 553 | chip->model.init(chip); |
519 | 554 | ||