diff options
Diffstat (limited to 'sound/isa/opti9xx/opti92x-ad1848.c')
-rw-r--r-- | sound/isa/opti9xx/opti92x-ad1848.c | 120 |
1 files changed, 78 insertions, 42 deletions
diff --git a/sound/isa/opti9xx/opti92x-ad1848.c b/sound/isa/opti9xx/opti92x-ad1848.c index a4af53b5c1cf..becd90d7536d 100644 --- a/sound/isa/opti9xx/opti92x-ad1848.c +++ b/sound/isa/opti9xx/opti92x-ad1848.c | |||
@@ -144,12 +144,8 @@ struct snd_opti9xx { | |||
144 | 144 | ||
145 | spinlock_t lock; | 145 | spinlock_t lock; |
146 | 146 | ||
147 | long wss_base; | ||
147 | int irq; | 148 | int irq; |
148 | |||
149 | #ifdef CONFIG_PNP | ||
150 | struct pnp_dev *dev; | ||
151 | struct pnp_dev *devmpu; | ||
152 | #endif /* CONFIG_PNP */ | ||
153 | }; | 149 | }; |
154 | 150 | ||
155 | static int snd_opti9xx_pnp_is_probed; | 151 | static int snd_opti9xx_pnp_is_probed; |
@@ -159,12 +155,17 @@ static int snd_opti9xx_pnp_is_probed; | |||
159 | static struct pnp_card_device_id snd_opti9xx_pnpids[] = { | 155 | static struct pnp_card_device_id snd_opti9xx_pnpids[] = { |
160 | #ifndef OPTi93X | 156 | #ifndef OPTi93X |
161 | /* OPTi 82C924 */ | 157 | /* OPTi 82C924 */ |
162 | { .id = "OPT0924", .devs = { { "OPT0000" }, { "OPT0002" } }, .driver_data = 0x0924 }, | 158 | { .id = "OPT0924", |
159 | .devs = { { "OPT0000" }, { "OPT0002" }, { "OPT0005" } }, | ||
160 | .driver_data = 0x0924 }, | ||
163 | /* OPTi 82C925 */ | 161 | /* OPTi 82C925 */ |
164 | { .id = "OPT0925", .devs = { { "OPT9250" }, { "OPT0002" } }, .driver_data = 0x0925 }, | 162 | { .id = "OPT0925", |
163 | .devs = { { "OPT9250" }, { "OPT0002" }, { "OPT0005" } }, | ||
164 | .driver_data = 0x0925 }, | ||
165 | #else | 165 | #else |
166 | /* OPTi 82C931/3 */ | 166 | /* OPTi 82C931/3 */ |
167 | { .id = "OPT0931", .devs = { { "OPT9310" }, { "OPT0002" } }, .driver_data = 0x0931 }, | 167 | { .id = "OPT0931", .devs = { { "OPT9310" }, { "OPT0002" } }, |
168 | .driver_data = 0x0931 }, | ||
168 | #endif /* OPTi93X */ | 169 | #endif /* OPTi93X */ |
169 | { .id = "" } | 170 | { .id = "" } |
170 | }; | 171 | }; |
@@ -207,24 +208,34 @@ static int __devinit snd_opti9xx_init(struct snd_opti9xx *chip, | |||
207 | chip->hardware = hardware; | 208 | chip->hardware = hardware; |
208 | strcpy(chip->name, snd_opti9xx_names[hardware]); | 209 | strcpy(chip->name, snd_opti9xx_names[hardware]); |
209 | 210 | ||
210 | chip->mc_base_size = opti9xx_mc_size[hardware]; | ||
211 | |||
212 | spin_lock_init(&chip->lock); | 211 | spin_lock_init(&chip->lock); |
213 | 212 | ||
214 | chip->irq = -1; | 213 | chip->irq = -1; |
215 | 214 | ||
215 | #ifndef OPTi93X | ||
216 | #ifdef CONFIG_PNP | ||
217 | if (isapnp && chip->mc_base) | ||
218 | /* PnP resource gives the least 10 bits */ | ||
219 | chip->mc_base |= 0xc00; | ||
220 | #endif /* CONFIG_PNP */ | ||
221 | else { | ||
222 | chip->mc_base = 0xf8c; | ||
223 | chip->mc_base_size = opti9xx_mc_size[hardware]; | ||
224 | } | ||
225 | #else | ||
226 | chip->mc_base_size = opti9xx_mc_size[hardware]; | ||
227 | #endif | ||
228 | |||
216 | switch (hardware) { | 229 | switch (hardware) { |
217 | #ifndef OPTi93X | 230 | #ifndef OPTi93X |
218 | case OPTi9XX_HW_82C928: | 231 | case OPTi9XX_HW_82C928: |
219 | case OPTi9XX_HW_82C929: | 232 | case OPTi9XX_HW_82C929: |
220 | chip->mc_base = 0xf8c; | ||
221 | chip->password = (hardware == OPTi9XX_HW_82C928) ? 0xe2 : 0xe3; | 233 | chip->password = (hardware == OPTi9XX_HW_82C928) ? 0xe2 : 0xe3; |
222 | chip->pwd_reg = 3; | 234 | chip->pwd_reg = 3; |
223 | break; | 235 | break; |
224 | 236 | ||
225 | case OPTi9XX_HW_82C924: | 237 | case OPTi9XX_HW_82C924: |
226 | case OPTi9XX_HW_82C925: | 238 | case OPTi9XX_HW_82C925: |
227 | chip->mc_base = 0xf8c; | ||
228 | chip->password = 0xe5; | 239 | chip->password = 0xe5; |
229 | chip->pwd_reg = 3; | 240 | chip->pwd_reg = 3; |
230 | break; | 241 | break; |
@@ -292,7 +303,7 @@ static unsigned char snd_opti9xx_read(struct snd_opti9xx *chip, | |||
292 | spin_unlock_irqrestore(&chip->lock, flags); | 303 | spin_unlock_irqrestore(&chip->lock, flags); |
293 | return retval; | 304 | return retval; |
294 | } | 305 | } |
295 | 306 | ||
296 | static void snd_opti9xx_write(struct snd_opti9xx *chip, unsigned char reg, | 307 | static void snd_opti9xx_write(struct snd_opti9xx *chip, unsigned char reg, |
297 | unsigned char value) | 308 | unsigned char value) |
298 | { | 309 | { |
@@ -341,7 +352,7 @@ static void snd_opti9xx_write(struct snd_opti9xx *chip, unsigned char reg, | |||
341 | 352 | ||
342 | 353 | ||
343 | static int __devinit snd_opti9xx_configure(struct snd_opti9xx *chip, | 354 | static int __devinit snd_opti9xx_configure(struct snd_opti9xx *chip, |
344 | long wss_base, | 355 | long port, |
345 | int irq, int dma1, int dma2, | 356 | int irq, int dma1, int dma2, |
346 | long mpu_port, int mpu_irq) | 357 | long mpu_port, int mpu_irq) |
347 | { | 358 | { |
@@ -354,16 +365,23 @@ static int __devinit snd_opti9xx_configure(struct snd_opti9xx *chip, | |||
354 | switch (chip->hardware) { | 365 | switch (chip->hardware) { |
355 | #ifndef OPTi93X | 366 | #ifndef OPTi93X |
356 | case OPTi9XX_HW_82C924: | 367 | case OPTi9XX_HW_82C924: |
368 | /* opti 929 mode (?), OPL3 clock output, audio enable */ | ||
357 | snd_opti9xx_write_mask(chip, OPTi9XX_MC_REG(4), 0xf0, 0xfc); | 369 | snd_opti9xx_write_mask(chip, OPTi9XX_MC_REG(4), 0xf0, 0xfc); |
370 | /* enable wave audio */ | ||
358 | snd_opti9xx_write_mask(chip, OPTi9XX_MC_REG(6), 0x02, 0x02); | 371 | snd_opti9xx_write_mask(chip, OPTi9XX_MC_REG(6), 0x02, 0x02); |
359 | 372 | ||
360 | case OPTi9XX_HW_82C925: | 373 | case OPTi9XX_HW_82C925: |
374 | /* enable WSS mode */ | ||
361 | snd_opti9xx_write_mask(chip, OPTi9XX_MC_REG(1), 0x80, 0x80); | 375 | snd_opti9xx_write_mask(chip, OPTi9XX_MC_REG(1), 0x80, 0x80); |
376 | /* OPL3 FM synthesis */ | ||
362 | snd_opti9xx_write_mask(chip, OPTi9XX_MC_REG(2), 0x00, 0x20); | 377 | snd_opti9xx_write_mask(chip, OPTi9XX_MC_REG(2), 0x00, 0x20); |
378 | /* disable Sound Blaster IRQ and DMA */ | ||
363 | snd_opti9xx_write_mask(chip, OPTi9XX_MC_REG(3), 0xf0, 0xff); | 379 | snd_opti9xx_write_mask(chip, OPTi9XX_MC_REG(3), 0xf0, 0xff); |
364 | #ifdef CS4231 | 380 | #ifdef CS4231 |
381 | /* cs4231/4248 fix enabled */ | ||
365 | snd_opti9xx_write_mask(chip, OPTi9XX_MC_REG(5), 0x02, 0x02); | 382 | snd_opti9xx_write_mask(chip, OPTi9XX_MC_REG(5), 0x02, 0x02); |
366 | #else | 383 | #else |
384 | /* cs4231/4248 fix disabled */ | ||
367 | snd_opti9xx_write_mask(chip, OPTi9XX_MC_REG(5), 0x00, 0x02); | 385 | snd_opti9xx_write_mask(chip, OPTi9XX_MC_REG(5), 0x00, 0x02); |
368 | #endif /* CS4231 */ | 386 | #endif /* CS4231 */ |
369 | break; | 387 | break; |
@@ -411,21 +429,26 @@ static int __devinit snd_opti9xx_configure(struct snd_opti9xx *chip, | |||
411 | return -EINVAL; | 429 | return -EINVAL; |
412 | } | 430 | } |
413 | 431 | ||
414 | switch (wss_base) { | 432 | /* PnP resource says it decodes only 10 bits of address */ |
415 | case 0x530: | 433 | switch (port & 0x3ff) { |
434 | case 0x130: | ||
435 | chip->wss_base = 0x530; | ||
416 | wss_base_bits = 0x00; | 436 | wss_base_bits = 0x00; |
417 | break; | 437 | break; |
418 | case 0x604: | 438 | case 0x204: |
439 | chip->wss_base = 0x604; | ||
419 | wss_base_bits = 0x03; | 440 | wss_base_bits = 0x03; |
420 | break; | 441 | break; |
421 | case 0xe80: | 442 | case 0x280: |
443 | chip->wss_base = 0xe80; | ||
422 | wss_base_bits = 0x01; | 444 | wss_base_bits = 0x01; |
423 | break; | 445 | break; |
424 | case 0xf40: | 446 | case 0x340: |
447 | chip->wss_base = 0xf40; | ||
425 | wss_base_bits = 0x02; | 448 | wss_base_bits = 0x02; |
426 | break; | 449 | break; |
427 | default: | 450 | default: |
428 | snd_printk(KERN_WARNING "WSS port 0x%lx not valid\n", wss_base); | 451 | snd_printk(KERN_WARNING "WSS port 0x%lx not valid\n", port); |
429 | goto __skip_base; | 452 | goto __skip_base; |
430 | } | 453 | } |
431 | snd_opti9xx_write_mask(chip, OPTi9XX_MC_REG(1), wss_base_bits << 4, 0x30); | 454 | snd_opti9xx_write_mask(chip, OPTi9XX_MC_REG(1), wss_base_bits << 4, 0x30); |
@@ -487,7 +510,7 @@ __skip_base: | |||
487 | #endif /* CS4231 || OPTi93X */ | 510 | #endif /* CS4231 || OPTi93X */ |
488 | 511 | ||
489 | #ifndef OPTi93X | 512 | #ifndef OPTi93X |
490 | outb(irq_bits << 3 | dma_bits, wss_base); | 513 | outb(irq_bits << 3 | dma_bits, chip->wss_base); |
491 | #else /* OPTi93X */ | 514 | #else /* OPTi93X */ |
492 | snd_opti9xx_write(chip, OPTi9XX_MC_REG(3), (irq_bits << 3 | dma_bits)); | 515 | snd_opti9xx_write(chip, OPTi9XX_MC_REG(3), (irq_bits << 3 | dma_bits)); |
493 | #endif /* OPTi93X */ | 516 | #endif /* OPTi93X */ |
@@ -729,15 +752,15 @@ static int __devinit snd_card_opti9xx_pnp(struct snd_opti9xx *chip, | |||
729 | { | 752 | { |
730 | struct pnp_dev *pdev; | 753 | struct pnp_dev *pdev; |
731 | int err; | 754 | int err; |
755 | struct pnp_dev *devmpu; | ||
756 | #ifndef OPTi93X | ||
757 | struct pnp_dev *devmc; | ||
758 | #endif | ||
732 | 759 | ||
733 | chip->dev = pnp_request_card_device(card, pid->devs[0].id, NULL); | 760 | pdev = pnp_request_card_device(card, pid->devs[0].id, NULL); |
734 | if (chip->dev == NULL) | 761 | if (pdev == NULL) |
735 | return -EBUSY; | 762 | return -EBUSY; |
736 | 763 | ||
737 | chip->devmpu = pnp_request_card_device(card, pid->devs[1].id, NULL); | ||
738 | |||
739 | pdev = chip->dev; | ||
740 | |||
741 | err = pnp_activate_dev(pdev); | 764 | err = pnp_activate_dev(pdev); |
742 | if (err < 0) { | 765 | if (err < 0) { |
743 | snd_printk(KERN_ERR "AUDIO pnp configure failure: %d\n", err); | 766 | snd_printk(KERN_ERR "AUDIO pnp configure failure: %d\n", err); |
@@ -750,9 +773,24 @@ static int __devinit snd_card_opti9xx_pnp(struct snd_opti9xx *chip, | |||
750 | chip->mc_indir_index = pnp_port_start(pdev, 3) + 2; | 773 | chip->mc_indir_index = pnp_port_start(pdev, 3) + 2; |
751 | chip->mc_indir_size = pnp_port_len(pdev, 3) - 2; | 774 | chip->mc_indir_size = pnp_port_len(pdev, 3) - 2; |
752 | #else | 775 | #else |
753 | if (pid->driver_data != 0x0924) | 776 | devmc = pnp_request_card_device(card, pid->devs[2].id, NULL); |
754 | port = pnp_port_start(pdev, 1); | 777 | if (devmc == NULL) |
778 | return -EBUSY; | ||
779 | |||
780 | err = pnp_activate_dev(devmc); | ||
781 | if (err < 0) { | ||
782 | snd_printk(KERN_ERR "MC pnp configure failure: %d\n", err); | ||
783 | return err; | ||
784 | } | ||
785 | |||
786 | port = pnp_port_start(pdev, 1); | ||
755 | fm_port = pnp_port_start(pdev, 2) + 8; | 787 | fm_port = pnp_port_start(pdev, 2) + 8; |
788 | /* | ||
789 | * The MC(0) is never accessed and card does not | ||
790 | * include it in the PnP resource range. OPTI93x include it. | ||
791 | */ | ||
792 | chip->mc_base = pnp_port_start(devmc, 0) - 1; | ||
793 | chip->mc_base_size = pnp_port_len(devmc, 0) + 1; | ||
756 | #endif /* OPTi93X */ | 794 | #endif /* OPTi93X */ |
757 | irq = pnp_irq(pdev, 0); | 795 | irq = pnp_irq(pdev, 0); |
758 | dma1 = pnp_dma(pdev, 0); | 796 | dma1 = pnp_dma(pdev, 0); |
@@ -760,16 +798,16 @@ static int __devinit snd_card_opti9xx_pnp(struct snd_opti9xx *chip, | |||
760 | dma2 = pnp_dma(pdev, 1); | 798 | dma2 = pnp_dma(pdev, 1); |
761 | #endif /* CS4231 || OPTi93X */ | 799 | #endif /* CS4231 || OPTi93X */ |
762 | 800 | ||
763 | pdev = chip->devmpu; | 801 | devmpu = pnp_request_card_device(card, pid->devs[1].id, NULL); |
764 | if (pdev && mpu_port > 0) { | 802 | |
765 | err = pnp_activate_dev(pdev); | 803 | if (devmpu && mpu_port > 0) { |
804 | err = pnp_activate_dev(devmpu); | ||
766 | if (err < 0) { | 805 | if (err < 0) { |
767 | snd_printk(KERN_ERR "AUDIO pnp configure failure\n"); | 806 | snd_printk(KERN_ERR "MPU401 pnp configure failure\n"); |
768 | mpu_port = -1; | 807 | mpu_port = -1; |
769 | chip->devmpu = NULL; | ||
770 | } else { | 808 | } else { |
771 | mpu_port = pnp_port_start(pdev, 0); | 809 | mpu_port = pnp_port_start(devmpu, 0); |
772 | mpu_irq = pnp_irq(pdev, 0); | 810 | mpu_irq = pnp_irq(devmpu, 0); |
773 | } | 811 | } |
774 | } | 812 | } |
775 | return pid->driver_data; | 813 | return pid->driver_data; |
@@ -824,7 +862,7 @@ static int __devinit snd_opti9xx_probe(struct snd_card *card) | |||
824 | if (error) | 862 | if (error) |
825 | return error; | 863 | return error; |
826 | 864 | ||
827 | error = snd_wss_create(card, port + 4, -1, irq, dma1, xdma2, | 865 | error = snd_wss_create(card, chip->wss_base + 4, -1, irq, dma1, xdma2, |
828 | #ifdef OPTi93X | 866 | #ifdef OPTi93X |
829 | WSS_HW_OPTI93X, WSS_HWSHARE_IRQ, | 867 | WSS_HW_OPTI93X, WSS_HWSHARE_IRQ, |
830 | #else | 868 | #else |
@@ -865,10 +903,11 @@ static int __devinit snd_opti9xx_probe(struct snd_card *card) | |||
865 | sprintf(card->shortname, "OPTi %s", card->driver); | 903 | sprintf(card->shortname, "OPTi %s", card->driver); |
866 | #if defined(CS4231) || defined(OPTi93X) | 904 | #if defined(CS4231) || defined(OPTi93X) |
867 | sprintf(card->longname, "%s, %s at 0x%lx, irq %d, dma %d&%d", | 905 | sprintf(card->longname, "%s, %s at 0x%lx, irq %d, dma %d&%d", |
868 | card->shortname, pcm->name, port + 4, irq, dma1, xdma2); | 906 | card->shortname, pcm->name, |
907 | chip->wss_base + 4, irq, dma1, xdma2); | ||
869 | #else | 908 | #else |
870 | sprintf(card->longname, "%s, %s at 0x%lx, irq %d, dma %d", | 909 | sprintf(card->longname, "%s, %s at 0x%lx, irq %d, dma %d", |
871 | card->shortname, pcm->name, port + 4, irq, dma1); | 910 | card->shortname, pcm->name, chip->wss_base + 4, irq, dma1); |
872 | #endif /* CS4231 || OPTi93X */ | 911 | #endif /* CS4231 || OPTi93X */ |
873 | 912 | ||
874 | if (mpu_port <= 0 || mpu_port == SNDRV_AUTO_PORT) | 913 | if (mpu_port <= 0 || mpu_port == SNDRV_AUTO_PORT) |
@@ -1062,9 +1101,6 @@ static int __devinit snd_opti9xx_pnp_probe(struct pnp_card_link *pcard, | |||
1062 | snd_card_free(card); | 1101 | snd_card_free(card); |
1063 | return error; | 1102 | return error; |
1064 | } | 1103 | } |
1065 | if (hw <= OPTi9XX_HW_82C930) | ||
1066 | chip->mc_base -= 0x80; | ||
1067 | |||
1068 | error = snd_opti9xx_read_check(chip); | 1104 | error = snd_opti9xx_read_check(chip); |
1069 | if (error) { | 1105 | if (error) { |
1070 | snd_printk(KERN_ERR "OPTI chip not found\n"); | 1106 | snd_printk(KERN_ERR "OPTI chip not found\n"); |