aboutsummaryrefslogtreecommitdiffstats
path: root/sound/isa/opti9xx/opti92x-ad1848.c
diff options
context:
space:
mode:
authorKrzysztof Helt <krzysztof.h1@wp.pl>2010-03-03 13:41:44 -0500
committerTakashi Iwai <tiwai@suse.de>2010-03-03 16:36:18 -0500
commitfd8d47351d2e241f3168eeb697ce55cc28c75b78 (patch)
treebdba27bec2d326277f0454c8cd155f47c03bc069 /sound/isa/opti9xx/opti92x-ad1848.c
parent864c11080cf365720103042444534a1e94d42bac (diff)
ALSA: opti92x: use PnP data to select Master Control port
The Master Control port (MC) is available as the last PnP resource (OPT005). Use this value instead fo guessing. Also, add some comments to the code. Signed-off-by: Krzysztof Helt <krzysztof.h1@wp.pl> Signed-off-by: Takashi Iwai <tiwai@suse.de>
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");