aboutsummaryrefslogtreecommitdiffstats
path: root/sound
diff options
context:
space:
mode:
authorKrzysztof Helt <krzysztof.h1@wp.pl>2009-12-04 12:30:18 -0500
committerTakashi Iwai <tiwai@suse.de>2009-12-08 06:22:52 -0500
commite6960e194a7dfb8197822225e04eca95fbd61a7f (patch)
tree8c06707f7c4846fd43978de061a7375105c8fb9a /sound
parent86e1d57e4f24ca27ce813bdc2afaac4adafcbaf4 (diff)
ALSA: opti93x: set MC indirect registers base from PnP data
The PnP data on the OPTI931 and OPTI933 contains io port range for the MC indirect registers. Use the PnP range instead of hardwired value 0xE0E. Also, request region of MC indirect registers so it is marked as used to other drivers (this was missing previously). Signed-off-by: Krzysztof Helt <krzysztof.h1@wp.pl> Signed-off-by: Takashi Iwai <tiwai@suse.de>
Diffstat (limited to 'sound')
-rw-r--r--sound/isa/opti9xx/opti92x-ad1848.c112
1 files changed, 67 insertions, 45 deletions
diff --git a/sound/isa/opti9xx/opti92x-ad1848.c b/sound/isa/opti9xx/opti92x-ad1848.c
index d08c3890644..8c88401c79b 100644
--- a/sound/isa/opti9xx/opti92x-ad1848.c
+++ b/sound/isa/opti9xx/opti92x-ad1848.c
@@ -135,6 +135,8 @@ struct snd_opti9xx {
135 unsigned long mc_base_size; 135 unsigned long mc_base_size;
136#ifdef OPTi93X 136#ifdef OPTi93X
137 unsigned long mc_indir_index; 137 unsigned long mc_indir_index;
138 unsigned long mc_indir_size;
139 struct resource *res_mc_indir;
138 struct snd_wss *codec; 140 struct snd_wss *codec;
139#endif /* OPTi93X */ 141#endif /* OPTi93X */
140 unsigned long pwd_reg; 142 unsigned long pwd_reg;
@@ -231,7 +233,10 @@ static int __devinit snd_opti9xx_init(struct snd_opti9xx *chip,
231 case OPTi9XX_HW_82C931: 233 case OPTi9XX_HW_82C931:
232 case OPTi9XX_HW_82C933: 234 case OPTi9XX_HW_82C933:
233 chip->mc_base = (hardware == OPTi9XX_HW_82C930) ? 0xf8f : 0xf8d; 235 chip->mc_base = (hardware == OPTi9XX_HW_82C930) ? 0xf8f : 0xf8d;
234 chip->mc_indir_index = 0xe0e; 236 if (!chip->mc_indir_index) {
237 chip->mc_indir_index = 0xe0e;
238 chip->mc_indir_size = 2;
239 }
235 chip->password = 0xe4; 240 chip->password = 0xe4;
236 chip->pwd_reg = 0; 241 chip->pwd_reg = 0;
237 break; 242 break;
@@ -560,57 +565,69 @@ static irqreturn_t snd_opti93x_interrupt(int irq, void *dev_id)
560 565
561#endif /* OPTi93X */ 566#endif /* OPTi93X */
562 567
563static int __devinit snd_card_opti9xx_detect(struct snd_card *card, 568static int __devinit snd_opti9xx_read_check(struct snd_opti9xx *chip)
564 struct snd_opti9xx *chip)
565{ 569{
566 int i, err; 570 unsigned char value;
571#ifdef OPTi93X
572 unsigned long flags;
573#endif
567 574
575 chip->res_mc_base = request_region(chip->mc_base, chip->mc_base_size,
576 "OPTi9xx MC");
577 if (chip->res_mc_base == NULL)
578 return -EBUSY;
568#ifndef OPTi93X 579#ifndef OPTi93X
569 for (i = OPTi9XX_HW_82C928; i < OPTi9XX_HW_82C930; i++) { 580 value = snd_opti9xx_read(chip, OPTi9XX_MC_REG(1));
570 unsigned char value; 581 if (value != 0xff && value != inb(chip->mc_base + OPTi9XX_MC_REG(1)))
582 if (value == snd_opti9xx_read(chip, OPTi9XX_MC_REG(1)))
583 return 0;
584#else /* OPTi93X */
585 chip->res_mc_indir = request_region(chip->mc_indir_index,
586 chip->mc_indir_size,
587 "OPTi93x MC");
588 if (chip->res_mc_indir == NULL)
589 return -EBUSY;
571 590
572 if ((err = snd_opti9xx_init(chip, i)) < 0) 591 spin_lock_irqsave(&chip->lock, flags);
573 return err; 592 outb(chip->password, chip->mc_base + chip->pwd_reg);
593 outb(((chip->mc_indir_index & 0x1f0) >> 4), chip->mc_base);
594 spin_unlock_irqrestore(&chip->lock, flags);
574 595
575 if ((chip->res_mc_base = request_region(chip->mc_base, chip->mc_base_size, "OPTi9xx MC")) == NULL) 596 value = snd_opti9xx_read(chip, OPTi9XX_MC_REG(7));
576 continue; 597 snd_opti9xx_write(chip, OPTi9XX_MC_REG(7), 0xff - value);
598 if (snd_opti9xx_read(chip, OPTi9XX_MC_REG(7)) == 0xff - value)
599 return 0;
577 600
578 value = snd_opti9xx_read(chip, OPTi9XX_MC_REG(1)); 601 release_and_free_resource(chip->res_mc_indir);
579 if ((value != 0xff) && (value != inb(chip->mc_base + 1))) 602 chip->res_mc_indir = NULL;
580 if (value == snd_opti9xx_read(chip, OPTi9XX_MC_REG(1))) 603#endif /* OPTi93X */
581 return 1; 604 release_and_free_resource(chip->res_mc_base);
605 chip->res_mc_base = NULL;
582 606
583 release_and_free_resource(chip->res_mc_base); 607 return -ENODEV;
584 chip->res_mc_base = NULL; 608}
585 609
586 } 610static int __devinit snd_card_opti9xx_detect(struct snd_card *card,
587#else /* OPTi93X */ 611 struct snd_opti9xx *chip)
588 for (i = OPTi9XX_HW_82C931; i >= OPTi9XX_HW_82C930; i--) { 612{
589 unsigned long flags; 613 int i, err;
590 unsigned char value;
591 614
592 if ((err = snd_opti9xx_init(chip, i)) < 0) 615#ifndef OPTi93X
616 for (i = OPTi9XX_HW_82C928; i < OPTi9XX_HW_82C930; i++) {
617#else
618 for (i = OPTi9XX_HW_82C931; i >= OPTi9XX_HW_82C930; i--) {
619#endif
620 err = snd_opti9xx_init(chip, i);
621 if (err < 0)
593 return err; 622 return err;
594 623
595 if ((chip->res_mc_base = request_region(chip->mc_base, chip->mc_base_size, "OPTi9xx MC")) == NULL) 624 err = snd_opti9xx_read_check(chip);
596 continue; 625 if (err == 0)
597
598 spin_lock_irqsave(&chip->lock, flags);
599 outb(chip->password, chip->mc_base + chip->pwd_reg);
600 outb(((chip->mc_indir_index & (1 << 8)) >> 4) |
601 ((chip->mc_indir_index & 0xf0) >> 4), chip->mc_base);
602 spin_unlock_irqrestore(&chip->lock, flags);
603
604 value = snd_opti9xx_read(chip, OPTi9XX_MC_REG(7));
605 snd_opti9xx_write(chip, OPTi9XX_MC_REG(7), 0xff - value);
606 if (snd_opti9xx_read(chip, OPTi9XX_MC_REG(7)) == 0xff - value)
607 return 1; 626 return 1;
608 627#ifdef OPTi93X
609 release_and_free_resource(chip->res_mc_base); 628 chip->mc_indir_index = 0;
610 chip->res_mc_base = NULL; 629#endif
611 } 630 }
612#endif /* OPTi93X */
613
614 return -ENODEV; 631 return -ENODEV;
615} 632}
616 633
@@ -639,6 +656,8 @@ static int __devinit snd_card_opti9xx_pnp(struct snd_opti9xx *chip,
639#ifdef OPTi93X 656#ifdef OPTi93X
640 port = pnp_port_start(pdev, 0) - 4; 657 port = pnp_port_start(pdev, 0) - 4;
641 fm_port = pnp_port_start(pdev, 1) + 8; 658 fm_port = pnp_port_start(pdev, 1) + 8;
659 chip->mc_indir_index = pnp_port_start(pdev, 3) + 2;
660 chip->mc_indir_size = pnp_port_len(pdev, 3) - 2;
642#else 661#else
643 if (pid->driver_data != 0x0924) 662 if (pid->driver_data != 0x0924)
644 port = pnp_port_start(pdev, 1); 663 port = pnp_port_start(pdev, 1);
@@ -669,7 +688,7 @@ static int __devinit snd_card_opti9xx_pnp(struct snd_opti9xx *chip,
669static void snd_card_opti9xx_free(struct snd_card *card) 688static void snd_card_opti9xx_free(struct snd_card *card)
670{ 689{
671 struct snd_opti9xx *chip = card->private_data; 690 struct snd_opti9xx *chip = card->private_data;
672 691
673 if (chip) { 692 if (chip) {
674#ifdef OPTi93X 693#ifdef OPTi93X
675 struct snd_wss *codec = chip->codec; 694 struct snd_wss *codec = chip->codec;
@@ -677,6 +696,7 @@ static void snd_card_opti9xx_free(struct snd_card *card)
677 disable_irq(codec->irq); 696 disable_irq(codec->irq);
678 free_irq(codec->irq, codec); 697 free_irq(codec->irq, codec);
679 } 698 }
699 release_and_free_resource(chip->res_mc_indir);
680#endif 700#endif
681 release_and_free_resource(chip->res_mc_base); 701 release_and_free_resource(chip->res_mc_base);
682 } 702 }
@@ -696,11 +716,6 @@ static int __devinit snd_opti9xx_probe(struct snd_card *card)
696 struct snd_rawmidi *rmidi; 716 struct snd_rawmidi *rmidi;
697 struct snd_hwdep *synth; 717 struct snd_hwdep *synth;
698 718
699 if (! chip->res_mc_base &&
700 (chip->res_mc_base = request_region(chip->mc_base, chip->mc_base_size,
701 "OPTi9xx MC")) == NULL)
702 return -ENOMEM;
703
704#if defined(CS4231) || defined(OPTi93X) 719#if defined(CS4231) || defined(OPTi93X)
705 xdma2 = dma2; 720 xdma2 = dma2;
706#else 721#else
@@ -954,6 +969,13 @@ static int __devinit snd_opti9xx_pnp_probe(struct pnp_card_link *pcard,
954 } 969 }
955 if (hw <= OPTi9XX_HW_82C930) 970 if (hw <= OPTi9XX_HW_82C930)
956 chip->mc_base -= 0x80; 971 chip->mc_base -= 0x80;
972
973 error = snd_opti9xx_read_check(chip);
974 if (error) {
975 snd_printk(KERN_ERR "OPTI chip not found\n");
976 snd_card_free(card);
977 return error;
978 }
957 snd_card_set_dev(card, &pcard->card->dev); 979 snd_card_set_dev(card, &pcard->card->dev);
958 if ((error = snd_opti9xx_probe(card)) < 0) { 980 if ((error = snd_opti9xx_probe(card)) < 0) {
959 snd_card_free(card); 981 snd_card_free(card);