aboutsummaryrefslogtreecommitdiffstats
path: root/sound/isa/opti9xx/opti92x-ad1848.c
diff options
context:
space:
mode:
Diffstat (limited to 'sound/isa/opti9xx/opti92x-ad1848.c')
-rw-r--r--sound/isa/opti9xx/opti92x-ad1848.c120
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
155static int snd_opti9xx_pnp_is_probed; 151static int snd_opti9xx_pnp_is_probed;
@@ -159,12 +155,17 @@ static int snd_opti9xx_pnp_is_probed;
159static struct pnp_card_device_id snd_opti9xx_pnpids[] = { 155static 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
296static void snd_opti9xx_write(struct snd_opti9xx *chip, unsigned char reg, 307static 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
343static int __devinit snd_opti9xx_configure(struct snd_opti9xx *chip, 354static 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");