diff options
Diffstat (limited to 'sound/isa/opti9xx/opti92x-ad1848.c')
-rw-r--r-- | sound/isa/opti9xx/opti92x-ad1848.c | 110 |
1 files changed, 43 insertions, 67 deletions
diff --git a/sound/isa/opti9xx/opti92x-ad1848.c b/sound/isa/opti9xx/opti92x-ad1848.c index 5cd555325b9d..d08c38906449 100644 --- a/sound/isa/opti9xx/opti92x-ad1848.c +++ b/sound/isa/opti9xx/opti92x-ad1848.c | |||
@@ -141,15 +141,7 @@ struct snd_opti9xx { | |||
141 | 141 | ||
142 | spinlock_t lock; | 142 | spinlock_t lock; |
143 | 143 | ||
144 | long wss_base; | ||
145 | int irq; | 144 | int irq; |
146 | int dma1; | ||
147 | int dma2; | ||
148 | |||
149 | long fm_port; | ||
150 | |||
151 | long mpu_port; | ||
152 | int mpu_irq; | ||
153 | 145 | ||
154 | #ifdef CONFIG_PNP | 146 | #ifdef CONFIG_PNP |
155 | struct pnp_dev *dev; | 147 | struct pnp_dev *dev; |
@@ -216,13 +208,7 @@ static int __devinit snd_opti9xx_init(struct snd_opti9xx *chip, | |||
216 | 208 | ||
217 | spin_lock_init(&chip->lock); | 209 | spin_lock_init(&chip->lock); |
218 | 210 | ||
219 | chip->wss_base = -1; | ||
220 | chip->irq = -1; | 211 | chip->irq = -1; |
221 | chip->dma1 = -1; | ||
222 | chip->dma2 = -1; | ||
223 | chip->fm_port = -1; | ||
224 | chip->mpu_port = -1; | ||
225 | chip->mpu_irq = -1; | ||
226 | 212 | ||
227 | switch (hardware) { | 213 | switch (hardware) { |
228 | #ifndef OPTi93X | 214 | #ifndef OPTi93X |
@@ -348,7 +334,10 @@ static void snd_opti9xx_write(struct snd_opti9xx *chip, unsigned char reg, | |||
348 | (snd_opti9xx_read(chip, reg) & ~(mask)) | ((value) & (mask))) | 334 | (snd_opti9xx_read(chip, reg) & ~(mask)) | ((value) & (mask))) |
349 | 335 | ||
350 | 336 | ||
351 | static int __devinit snd_opti9xx_configure(struct snd_opti9xx *chip) | 337 | static int __devinit snd_opti9xx_configure(struct snd_opti9xx *chip, |
338 | long wss_base, | ||
339 | int irq, int dma1, int dma2, | ||
340 | long mpu_port, int mpu_irq) | ||
352 | { | 341 | { |
353 | unsigned char wss_base_bits; | 342 | unsigned char wss_base_bits; |
354 | unsigned char irq_bits; | 343 | unsigned char irq_bits; |
@@ -416,7 +405,7 @@ static int __devinit snd_opti9xx_configure(struct snd_opti9xx *chip) | |||
416 | return -EINVAL; | 405 | return -EINVAL; |
417 | } | 406 | } |
418 | 407 | ||
419 | switch (chip->wss_base) { | 408 | switch (wss_base) { |
420 | case 0x530: | 409 | case 0x530: |
421 | wss_base_bits = 0x00; | 410 | wss_base_bits = 0x00; |
422 | break; | 411 | break; |
@@ -430,14 +419,13 @@ static int __devinit snd_opti9xx_configure(struct snd_opti9xx *chip) | |||
430 | wss_base_bits = 0x02; | 419 | wss_base_bits = 0x02; |
431 | break; | 420 | break; |
432 | default: | 421 | default: |
433 | snd_printk(KERN_WARNING "WSS port 0x%lx not valid\n", | 422 | snd_printk(KERN_WARNING "WSS port 0x%lx not valid\n", wss_base); |
434 | chip->wss_base); | ||
435 | goto __skip_base; | 423 | goto __skip_base; |
436 | } | 424 | } |
437 | snd_opti9xx_write_mask(chip, OPTi9XX_MC_REG(1), wss_base_bits << 4, 0x30); | 425 | snd_opti9xx_write_mask(chip, OPTi9XX_MC_REG(1), wss_base_bits << 4, 0x30); |
438 | 426 | ||
439 | __skip_base: | 427 | __skip_base: |
440 | switch (chip->irq) { | 428 | switch (irq) { |
441 | //#ifdef OPTi93X | 429 | //#ifdef OPTi93X |
442 | case 5: | 430 | case 5: |
443 | irq_bits = 0x05; | 431 | irq_bits = 0x05; |
@@ -456,11 +444,11 @@ __skip_base: | |||
456 | irq_bits = 0x04; | 444 | irq_bits = 0x04; |
457 | break; | 445 | break; |
458 | default: | 446 | default: |
459 | snd_printk(KERN_WARNING "WSS irq # %d not valid\n", chip->irq); | 447 | snd_printk(KERN_WARNING "WSS irq # %d not valid\n", irq); |
460 | goto __skip_resources; | 448 | goto __skip_resources; |
461 | } | 449 | } |
462 | 450 | ||
463 | switch (chip->dma1) { | 451 | switch (dma1) { |
464 | case 0: | 452 | case 0: |
465 | dma_bits = 0x01; | 453 | dma_bits = 0x01; |
466 | break; | 454 | break; |
@@ -471,38 +459,36 @@ __skip_base: | |||
471 | dma_bits = 0x03; | 459 | dma_bits = 0x03; |
472 | break; | 460 | break; |
473 | default: | 461 | default: |
474 | snd_printk(KERN_WARNING "WSS dma1 # %d not valid\n", | 462 | snd_printk(KERN_WARNING "WSS dma1 # %d not valid\n", dma1); |
475 | chip->dma1); | ||
476 | goto __skip_resources; | 463 | goto __skip_resources; |
477 | } | 464 | } |
478 | 465 | ||
479 | #if defined(CS4231) || defined(OPTi93X) | 466 | #if defined(CS4231) || defined(OPTi93X) |
480 | if (chip->dma1 == chip->dma2) { | 467 | if (dma1 == dma2) { |
481 | snd_printk(KERN_ERR "don't want to share dmas\n"); | 468 | snd_printk(KERN_ERR "don't want to share dmas\n"); |
482 | return -EBUSY; | 469 | return -EBUSY; |
483 | } | 470 | } |
484 | 471 | ||
485 | switch (chip->dma2) { | 472 | switch (dma2) { |
486 | case 0: | 473 | case 0: |
487 | case 1: | 474 | case 1: |
488 | break; | 475 | break; |
489 | default: | 476 | default: |
490 | snd_printk(KERN_WARNING "WSS dma2 # %d not valid\n", | 477 | snd_printk(KERN_WARNING "WSS dma2 # %d not valid\n", dma2); |
491 | chip->dma2); | ||
492 | goto __skip_resources; | 478 | goto __skip_resources; |
493 | } | 479 | } |
494 | dma_bits |= 0x04; | 480 | dma_bits |= 0x04; |
495 | #endif /* CS4231 || OPTi93X */ | 481 | #endif /* CS4231 || OPTi93X */ |
496 | 482 | ||
497 | #ifndef OPTi93X | 483 | #ifndef OPTi93X |
498 | outb(irq_bits << 3 | dma_bits, chip->wss_base); | 484 | outb(irq_bits << 3 | dma_bits, wss_base); |
499 | #else /* OPTi93X */ | 485 | #else /* OPTi93X */ |
500 | snd_opti9xx_write(chip, OPTi9XX_MC_REG(3), (irq_bits << 3 | dma_bits)); | 486 | snd_opti9xx_write(chip, OPTi9XX_MC_REG(3), (irq_bits << 3 | dma_bits)); |
501 | #endif /* OPTi93X */ | 487 | #endif /* OPTi93X */ |
502 | 488 | ||
503 | __skip_resources: | 489 | __skip_resources: |
504 | if (chip->hardware > OPTi9XX_HW_82C928) { | 490 | if (chip->hardware > OPTi9XX_HW_82C928) { |
505 | switch (chip->mpu_port) { | 491 | switch (mpu_port) { |
506 | case 0: | 492 | case 0: |
507 | case -1: | 493 | case -1: |
508 | break; | 494 | break; |
@@ -520,12 +506,11 @@ __skip_resources: | |||
520 | break; | 506 | break; |
521 | default: | 507 | default: |
522 | snd_printk(KERN_WARNING | 508 | snd_printk(KERN_WARNING |
523 | "MPU-401 port 0x%lx not valid\n", | 509 | "MPU-401 port 0x%lx not valid\n", mpu_port); |
524 | chip->mpu_port); | ||
525 | goto __skip_mpu; | 510 | goto __skip_mpu; |
526 | } | 511 | } |
527 | 512 | ||
528 | switch (chip->mpu_irq) { | 513 | switch (mpu_irq) { |
529 | case 5: | 514 | case 5: |
530 | mpu_irq_bits = 0x02; | 515 | mpu_irq_bits = 0x02; |
531 | break; | 516 | break; |
@@ -540,12 +525,12 @@ __skip_resources: | |||
540 | break; | 525 | break; |
541 | default: | 526 | default: |
542 | snd_printk(KERN_WARNING "MPU-401 irq # %d not valid\n", | 527 | snd_printk(KERN_WARNING "MPU-401 irq # %d not valid\n", |
543 | chip->mpu_irq); | 528 | mpu_irq); |
544 | goto __skip_mpu; | 529 | goto __skip_mpu; |
545 | } | 530 | } |
546 | 531 | ||
547 | snd_opti9xx_write_mask(chip, OPTi9XX_MC_REG(6), | 532 | snd_opti9xx_write_mask(chip, OPTi9XX_MC_REG(6), |
548 | (chip->mpu_port <= 0) ? 0x00 : | 533 | (mpu_port <= 0) ? 0x00 : |
549 | 0x80 | mpu_port_bits << 5 | mpu_irq_bits << 3, | 534 | 0x80 | mpu_port_bits << 5 | mpu_irq_bits << 3, |
550 | 0xf8); | 535 | 0xf8); |
551 | } | 536 | } |
@@ -701,6 +686,7 @@ static int __devinit snd_opti9xx_probe(struct snd_card *card) | |||
701 | { | 686 | { |
702 | static long possible_ports[] = {0x530, 0xe80, 0xf40, 0x604, -1}; | 687 | static long possible_ports[] = {0x530, 0xe80, 0xf40, 0x604, -1}; |
703 | int error; | 688 | int error; |
689 | int xdma2; | ||
704 | struct snd_opti9xx *chip = card->private_data; | 690 | struct snd_opti9xx *chip = card->private_data; |
705 | struct snd_wss *codec; | 691 | struct snd_wss *codec; |
706 | #ifdef CS4231 | 692 | #ifdef CS4231 |
@@ -715,31 +701,25 @@ static int __devinit snd_opti9xx_probe(struct snd_card *card) | |||
715 | "OPTi9xx MC")) == NULL) | 701 | "OPTi9xx MC")) == NULL) |
716 | return -ENOMEM; | 702 | return -ENOMEM; |
717 | 703 | ||
718 | chip->wss_base = port; | ||
719 | chip->fm_port = fm_port; | ||
720 | chip->mpu_port = mpu_port; | ||
721 | chip->irq = irq; | ||
722 | chip->mpu_irq = mpu_irq; | ||
723 | chip->dma1 = dma1; | ||
724 | #if defined(CS4231) || defined(OPTi93X) | 704 | #if defined(CS4231) || defined(OPTi93X) |
725 | chip->dma2 = dma2; | 705 | xdma2 = dma2; |
726 | #else | 706 | #else |
727 | chip->dma2 = -1; | 707 | xdma2 = -1; |
728 | #endif | 708 | #endif |
729 | 709 | ||
730 | if (chip->wss_base == SNDRV_AUTO_PORT) { | 710 | if (port == SNDRV_AUTO_PORT) { |
731 | chip->wss_base = snd_legacy_find_free_ioport(possible_ports, 4); | 711 | port = snd_legacy_find_free_ioport(possible_ports, 4); |
732 | if (chip->wss_base < 0) { | 712 | if (port < 0) { |
733 | snd_printk(KERN_ERR "unable to find a free WSS port\n"); | 713 | snd_printk(KERN_ERR "unable to find a free WSS port\n"); |
734 | return -EBUSY; | 714 | return -EBUSY; |
735 | } | 715 | } |
736 | } | 716 | } |
737 | error = snd_opti9xx_configure(chip); | 717 | error = snd_opti9xx_configure(chip, port, irq, dma1, xdma2, |
718 | mpu_port, mpu_irq); | ||
738 | if (error) | 719 | if (error) |
739 | return error; | 720 | return error; |
740 | 721 | ||
741 | error = snd_wss_create(card, chip->wss_base + 4, -1, | 722 | error = snd_wss_create(card, port + 4, -1, irq, dma1, xdma2, |
742 | chip->irq, chip->dma1, chip->dma2, | ||
743 | #ifdef OPTi93X | 723 | #ifdef OPTi93X |
744 | WSS_HW_OPTI93X, WSS_HWSHARE_IRQ, | 724 | WSS_HW_OPTI93X, WSS_HWSHARE_IRQ, |
745 | #else | 725 | #else |
@@ -763,35 +743,35 @@ static int __devinit snd_opti9xx_probe(struct snd_card *card) | |||
763 | return error; | 743 | return error; |
764 | #endif | 744 | #endif |
765 | #ifdef OPTi93X | 745 | #ifdef OPTi93X |
766 | error = request_irq(chip->irq, snd_opti93x_interrupt, | 746 | error = request_irq(irq, snd_opti93x_interrupt, |
767 | IRQF_DISABLED, DEV_NAME" - WSS", codec); | 747 | IRQF_DISABLED, DEV_NAME" - WSS", codec); |
768 | if (error < 0) { | 748 | if (error < 0) { |
769 | snd_printk(KERN_ERR "opti9xx: can't grab IRQ %d\n", chip->irq); | 749 | snd_printk(KERN_ERR "opti9xx: can't grab IRQ %d\n", chip->irq); |
770 | return error; | 750 | return error; |
771 | } | 751 | } |
772 | #endif | 752 | #endif |
753 | chip->irq = irq; | ||
773 | strcpy(card->driver, chip->name); | 754 | strcpy(card->driver, chip->name); |
774 | sprintf(card->shortname, "OPTi %s", card->driver); | 755 | sprintf(card->shortname, "OPTi %s", card->driver); |
775 | #if defined(CS4231) || defined(OPTi93X) | 756 | #if defined(CS4231) || defined(OPTi93X) |
776 | sprintf(card->longname, "%s, %s at 0x%lx, irq %d, dma %d&%d", | 757 | sprintf(card->longname, "%s, %s at 0x%lx, irq %d, dma %d&%d", |
777 | card->shortname, pcm->name, chip->wss_base + 4, | 758 | card->shortname, pcm->name, port + 4, irq, dma1, xdma2); |
778 | chip->irq, chip->dma1, chip->dma2); | ||
779 | #else | 759 | #else |
780 | sprintf(card->longname, "%s, %s at 0x%lx, irq %d, dma %d", | 760 | sprintf(card->longname, "%s, %s at 0x%lx, irq %d, dma %d", |
781 | card->shortname, pcm->name, chip->wss_base + 4, | 761 | card->shortname, pcm->name, port + 4, irq, dma1); |
782 | chip->irq, chip->dma1); | ||
783 | #endif /* CS4231 || OPTi93X */ | 762 | #endif /* CS4231 || OPTi93X */ |
784 | 763 | ||
785 | if (chip->mpu_port <= 0 || chip->mpu_port == SNDRV_AUTO_PORT) | 764 | if (mpu_port <= 0 || mpu_port == SNDRV_AUTO_PORT) |
786 | rmidi = NULL; | 765 | rmidi = NULL; |
787 | else | 766 | else { |
788 | if ((error = snd_mpu401_uart_new(card, 0, MPU401_HW_MPU401, | 767 | error = snd_mpu401_uart_new(card, 0, MPU401_HW_MPU401, |
789 | chip->mpu_port, 0, chip->mpu_irq, IRQF_DISABLED, | 768 | mpu_port, 0, mpu_irq, IRQF_DISABLED, &rmidi); |
790 | &rmidi))) | 769 | if (error) |
791 | snd_printk(KERN_WARNING "no MPU-401 device at 0x%lx?\n", | 770 | snd_printk(KERN_WARNING "no MPU-401 device at 0x%lx?\n", |
792 | chip->mpu_port); | 771 | mpu_port); |
772 | } | ||
793 | 773 | ||
794 | if (chip->fm_port > 0 && chip->fm_port != SNDRV_AUTO_PORT) { | 774 | if (fm_port > 0 && fm_port != SNDRV_AUTO_PORT) { |
795 | struct snd_opl3 *opl3 = NULL; | 775 | struct snd_opl3 *opl3 = NULL; |
796 | #ifndef OPTi93X | 776 | #ifndef OPTi93X |
797 | if (chip->hardware == OPTi9XX_HW_82C928 || | 777 | if (chip->hardware == OPTi9XX_HW_82C928 || |
@@ -801,9 +781,7 @@ static int __devinit snd_opti9xx_probe(struct snd_card *card) | |||
801 | /* assume we have an OPL4 */ | 781 | /* assume we have an OPL4 */ |
802 | snd_opti9xx_write_mask(chip, OPTi9XX_MC_REG(2), | 782 | snd_opti9xx_write_mask(chip, OPTi9XX_MC_REG(2), |
803 | 0x20, 0x20); | 783 | 0x20, 0x20); |
804 | if (snd_opl4_create(card, | 784 | if (snd_opl4_create(card, fm_port, fm_port - 8, |
805 | chip->fm_port, | ||
806 | chip->fm_port - 8, | ||
807 | 2, &opl3, &opl4) < 0) { | 785 | 2, &opl3, &opl4) < 0) { |
808 | /* no luck, use OPL3 instead */ | 786 | /* no luck, use OPL3 instead */ |
809 | snd_opti9xx_write_mask(chip, OPTi9XX_MC_REG(2), | 787 | snd_opti9xx_write_mask(chip, OPTi9XX_MC_REG(2), |
@@ -811,12 +789,10 @@ static int __devinit snd_opti9xx_probe(struct snd_card *card) | |||
811 | } | 789 | } |
812 | } | 790 | } |
813 | #endif /* !OPTi93X */ | 791 | #endif /* !OPTi93X */ |
814 | if (!opl3 && snd_opl3_create(card, | 792 | if (!opl3 && snd_opl3_create(card, fm_port, fm_port + 2, |
815 | chip->fm_port, | ||
816 | chip->fm_port + 2, | ||
817 | OPL3_HW_AUTO, 0, &opl3) < 0) { | 793 | OPL3_HW_AUTO, 0, &opl3) < 0) { |
818 | snd_printk(KERN_WARNING "no OPL device at 0x%lx-0x%lx\n", | 794 | snd_printk(KERN_WARNING "no OPL device at 0x%lx-0x%lx\n", |
819 | chip->fm_port, chip->fm_port + 4 - 1); | 795 | fm_port, fm_port + 4 - 1); |
820 | } | 796 | } |
821 | if (opl3) { | 797 | if (opl3) { |
822 | error = snd_opl3_hwdep_new(opl3, 0, 1, &synth); | 798 | error = snd_opl3_hwdep_new(opl3, 0, 1, &synth); |