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.c214
1 files changed, 172 insertions, 42 deletions
diff --git a/sound/isa/opti9xx/opti92x-ad1848.c b/sound/isa/opti9xx/opti92x-ad1848.c
index c8a8da0d4036..4d2d0405bdc7 100644
--- a/sound/isa/opti9xx/opti92x-ad1848.c
+++ b/sound/isa/opti9xx/opti92x-ad1848.c
@@ -33,6 +33,7 @@
33#include <asm/io.h> 33#include <asm/io.h>
34#include <asm/dma.h> 34#include <asm/dma.h>
35#include <sound/core.h> 35#include <sound/core.h>
36#include <sound/tlv.h>
36#include <sound/wss.h> 37#include <sound/wss.h>
37#include <sound/mpu401.h> 38#include <sound/mpu401.h>
38#include <sound/opl3.h> 39#include <sound/opl3.h>
@@ -143,12 +144,8 @@ struct snd_opti9xx {
143 144
144 spinlock_t lock; 145 spinlock_t lock;
145 146
147 long wss_base;
146 int irq; 148 int irq;
147
148#ifdef CONFIG_PNP
149 struct pnp_dev *dev;
150 struct pnp_dev *devmpu;
151#endif /* CONFIG_PNP */
152}; 149};
153 150
154static int snd_opti9xx_pnp_is_probed; 151static int snd_opti9xx_pnp_is_probed;
@@ -158,12 +155,17 @@ static int snd_opti9xx_pnp_is_probed;
158static struct pnp_card_device_id snd_opti9xx_pnpids[] = { 155static struct pnp_card_device_id snd_opti9xx_pnpids[] = {
159#ifndef OPTi93X 156#ifndef OPTi93X
160 /* OPTi 82C924 */ 157 /* OPTi 82C924 */
161 { .id = "OPT0924", .devs = { { "OPT0000" }, { "OPT0002" } }, .driver_data = 0x0924 }, 158 { .id = "OPT0924",
159 .devs = { { "OPT0000" }, { "OPT0002" }, { "OPT0005" } },
160 .driver_data = 0x0924 },
162 /* OPTi 82C925 */ 161 /* OPTi 82C925 */
163 { .id = "OPT0925", .devs = { { "OPT9250" }, { "OPT0002" } }, .driver_data = 0x0925 }, 162 { .id = "OPT0925",
163 .devs = { { "OPT9250" }, { "OPT0002" }, { "OPT0005" } },
164 .driver_data = 0x0925 },
164#else 165#else
165 /* OPTi 82C931/3 */ 166 /* OPTi 82C931/3 */
166 { .id = "OPT0931", .devs = { { "OPT9310" }, { "OPT0002" } }, .driver_data = 0x0931 }, 167 { .id = "OPT0931", .devs = { { "OPT9310" }, { "OPT0002" } },
168 .driver_data = 0x0931 },
167#endif /* OPTi93X */ 169#endif /* OPTi93X */
168 { .id = "" } 170 { .id = "" }
169}; 171};
@@ -206,24 +208,35 @@ static int __devinit snd_opti9xx_init(struct snd_opti9xx *chip,
206 chip->hardware = hardware; 208 chip->hardware = hardware;
207 strcpy(chip->name, snd_opti9xx_names[hardware]); 209 strcpy(chip->name, snd_opti9xx_names[hardware]);
208 210
209 chip->mc_base_size = opti9xx_mc_size[hardware];
210
211 spin_lock_init(&chip->lock); 211 spin_lock_init(&chip->lock);
212 212
213 chip->irq = -1; 213 chip->irq = -1;
214 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 else
221#endif /* CONFIG_PNP */
222 {
223 chip->mc_base = 0xf8c;
224 chip->mc_base_size = opti9xx_mc_size[hardware];
225 }
226#else
227 chip->mc_base_size = opti9xx_mc_size[hardware];
228#endif
229
215 switch (hardware) { 230 switch (hardware) {
216#ifndef OPTi93X 231#ifndef OPTi93X
217 case OPTi9XX_HW_82C928: 232 case OPTi9XX_HW_82C928:
218 case OPTi9XX_HW_82C929: 233 case OPTi9XX_HW_82C929:
219 chip->mc_base = 0xf8c;
220 chip->password = (hardware == OPTi9XX_HW_82C928) ? 0xe2 : 0xe3; 234 chip->password = (hardware == OPTi9XX_HW_82C928) ? 0xe2 : 0xe3;
221 chip->pwd_reg = 3; 235 chip->pwd_reg = 3;
222 break; 236 break;
223 237
224 case OPTi9XX_HW_82C924: 238 case OPTi9XX_HW_82C924:
225 case OPTi9XX_HW_82C925: 239 case OPTi9XX_HW_82C925:
226 chip->mc_base = 0xf8c;
227 chip->password = 0xe5; 240 chip->password = 0xe5;
228 chip->pwd_reg = 3; 241 chip->pwd_reg = 3;
229 break; 242 break;
@@ -291,7 +304,7 @@ static unsigned char snd_opti9xx_read(struct snd_opti9xx *chip,
291 spin_unlock_irqrestore(&chip->lock, flags); 304 spin_unlock_irqrestore(&chip->lock, flags);
292 return retval; 305 return retval;
293} 306}
294 307
295static void snd_opti9xx_write(struct snd_opti9xx *chip, unsigned char reg, 308static void snd_opti9xx_write(struct snd_opti9xx *chip, unsigned char reg,
296 unsigned char value) 309 unsigned char value)
297{ 310{
@@ -340,7 +353,7 @@ static void snd_opti9xx_write(struct snd_opti9xx *chip, unsigned char reg,
340 353
341 354
342static int __devinit snd_opti9xx_configure(struct snd_opti9xx *chip, 355static int __devinit snd_opti9xx_configure(struct snd_opti9xx *chip,
343 long wss_base, 356 long port,
344 int irq, int dma1, int dma2, 357 int irq, int dma1, int dma2,
345 long mpu_port, int mpu_irq) 358 long mpu_port, int mpu_irq)
346{ 359{
@@ -353,16 +366,23 @@ static int __devinit snd_opti9xx_configure(struct snd_opti9xx *chip,
353 switch (chip->hardware) { 366 switch (chip->hardware) {
354#ifndef OPTi93X 367#ifndef OPTi93X
355 case OPTi9XX_HW_82C924: 368 case OPTi9XX_HW_82C924:
369 /* opti 929 mode (?), OPL3 clock output, audio enable */
356 snd_opti9xx_write_mask(chip, OPTi9XX_MC_REG(4), 0xf0, 0xfc); 370 snd_opti9xx_write_mask(chip, OPTi9XX_MC_REG(4), 0xf0, 0xfc);
371 /* enable wave audio */
357 snd_opti9xx_write_mask(chip, OPTi9XX_MC_REG(6), 0x02, 0x02); 372 snd_opti9xx_write_mask(chip, OPTi9XX_MC_REG(6), 0x02, 0x02);
358 373
359 case OPTi9XX_HW_82C925: 374 case OPTi9XX_HW_82C925:
375 /* enable WSS mode */
360 snd_opti9xx_write_mask(chip, OPTi9XX_MC_REG(1), 0x80, 0x80); 376 snd_opti9xx_write_mask(chip, OPTi9XX_MC_REG(1), 0x80, 0x80);
377 /* OPL3 FM synthesis */
361 snd_opti9xx_write_mask(chip, OPTi9XX_MC_REG(2), 0x00, 0x20); 378 snd_opti9xx_write_mask(chip, OPTi9XX_MC_REG(2), 0x00, 0x20);
379 /* disable Sound Blaster IRQ and DMA */
362 snd_opti9xx_write_mask(chip, OPTi9XX_MC_REG(3), 0xf0, 0xff); 380 snd_opti9xx_write_mask(chip, OPTi9XX_MC_REG(3), 0xf0, 0xff);
363#ifdef CS4231 381#ifdef CS4231
382 /* cs4231/4248 fix enabled */
364 snd_opti9xx_write_mask(chip, OPTi9XX_MC_REG(5), 0x02, 0x02); 383 snd_opti9xx_write_mask(chip, OPTi9XX_MC_REG(5), 0x02, 0x02);
365#else 384#else
385 /* cs4231/4248 fix disabled */
366 snd_opti9xx_write_mask(chip, OPTi9XX_MC_REG(5), 0x00, 0x02); 386 snd_opti9xx_write_mask(chip, OPTi9XX_MC_REG(5), 0x00, 0x02);
367#endif /* CS4231 */ 387#endif /* CS4231 */
368 break; 388 break;
@@ -410,21 +430,26 @@ static int __devinit snd_opti9xx_configure(struct snd_opti9xx *chip,
410 return -EINVAL; 430 return -EINVAL;
411 } 431 }
412 432
413 switch (wss_base) { 433 /* PnP resource says it decodes only 10 bits of address */
414 case 0x530: 434 switch (port & 0x3ff) {
435 case 0x130:
436 chip->wss_base = 0x530;
415 wss_base_bits = 0x00; 437 wss_base_bits = 0x00;
416 break; 438 break;
417 case 0x604: 439 case 0x204:
440 chip->wss_base = 0x604;
418 wss_base_bits = 0x03; 441 wss_base_bits = 0x03;
419 break; 442 break;
420 case 0xe80: 443 case 0x280:
444 chip->wss_base = 0xe80;
421 wss_base_bits = 0x01; 445 wss_base_bits = 0x01;
422 break; 446 break;
423 case 0xf40: 447 case 0x340:
448 chip->wss_base = 0xf40;
424 wss_base_bits = 0x02; 449 wss_base_bits = 0x02;
425 break; 450 break;
426 default: 451 default:
427 snd_printk(KERN_WARNING "WSS port 0x%lx not valid\n", wss_base); 452 snd_printk(KERN_WARNING "WSS port 0x%lx not valid\n", port);
428 goto __skip_base; 453 goto __skip_base;
429 } 454 }
430 snd_opti9xx_write_mask(chip, OPTi9XX_MC_REG(1), wss_base_bits << 4, 0x30); 455 snd_opti9xx_write_mask(chip, OPTi9XX_MC_REG(1), wss_base_bits << 4, 0x30);
@@ -486,7 +511,7 @@ __skip_base:
486#endif /* CS4231 || OPTi93X */ 511#endif /* CS4231 || OPTi93X */
487 512
488#ifndef OPTi93X 513#ifndef OPTi93X
489 outb(irq_bits << 3 | dma_bits, wss_base); 514 outb(irq_bits << 3 | dma_bits, chip->wss_base);
490#else /* OPTi93X */ 515#else /* OPTi93X */
491 snd_opti9xx_write(chip, OPTi9XX_MC_REG(3), (irq_bits << 3 | dma_bits)); 516 snd_opti9xx_write(chip, OPTi9XX_MC_REG(3), (irq_bits << 3 | dma_bits));
492#endif /* OPTi93X */ 517#endif /* OPTi93X */
@@ -546,6 +571,93 @@ __skip_mpu:
546 571
547#ifdef OPTi93X 572#ifdef OPTi93X
548 573
574static const DECLARE_TLV_DB_SCALE(db_scale_5bit_3db_step, -9300, 300, 0);
575static const DECLARE_TLV_DB_SCALE(db_scale_5bit, -4650, 150, 0);
576static const DECLARE_TLV_DB_SCALE(db_scale_4bit_12db_max, -3300, 300, 0);
577
578static struct snd_kcontrol_new snd_opti93x_controls[] = {
579WSS_DOUBLE("Master Playback Switch", 0,
580 OPTi93X_OUT_LEFT, OPTi93X_OUT_RIGHT, 7, 7, 1, 1),
581WSS_DOUBLE_TLV("Master Playback Volume", 0,
582 OPTi93X_OUT_LEFT, OPTi93X_OUT_RIGHT, 1, 1, 31, 1,
583 db_scale_5bit_3db_step),
584WSS_DOUBLE_TLV("PCM Playback Volume", 0,
585 CS4231_LEFT_OUTPUT, CS4231_RIGHT_OUTPUT, 0, 0, 31, 1,
586 db_scale_5bit),
587WSS_DOUBLE_TLV("FM Playback Volume", 0,
588 CS4231_AUX2_LEFT_INPUT, CS4231_AUX2_RIGHT_INPUT, 1, 1, 15, 1,
589 db_scale_4bit_12db_max),
590WSS_DOUBLE("Line Playback Switch", 0,
591 CS4231_LEFT_LINE_IN, CS4231_RIGHT_LINE_IN, 7, 7, 1, 1),
592WSS_DOUBLE_TLV("Line Playback Volume", 0,
593 CS4231_LEFT_LINE_IN, CS4231_RIGHT_LINE_IN, 0, 0, 15, 1,
594 db_scale_4bit_12db_max),
595WSS_DOUBLE("Mic Playback Switch", 0,
596 OPTi93X_MIC_LEFT_INPUT, OPTi93X_MIC_RIGHT_INPUT, 7, 7, 1, 1),
597WSS_DOUBLE_TLV("Mic Playback Volume", 0,
598 OPTi93X_MIC_LEFT_INPUT, OPTi93X_MIC_RIGHT_INPUT, 1, 1, 15, 1,
599 db_scale_4bit_12db_max),
600WSS_DOUBLE_TLV("CD Playback Volume", 0,
601 CS4231_AUX1_LEFT_INPUT, CS4231_AUX1_RIGHT_INPUT, 1, 1, 15, 1,
602 db_scale_4bit_12db_max),
603WSS_DOUBLE("Aux Playback Switch", 0,
604 OPTi931_AUX_LEFT_INPUT, OPTi931_AUX_RIGHT_INPUT, 7, 7, 1, 1),
605WSS_DOUBLE_TLV("Aux Playback Volume", 0,
606 OPTi931_AUX_LEFT_INPUT, OPTi931_AUX_RIGHT_INPUT, 1, 1, 15, 1,
607 db_scale_4bit_12db_max),
608};
609
610static int __devinit snd_opti93x_mixer(struct snd_wss *chip)
611{
612 struct snd_card *card;
613 unsigned int idx;
614 struct snd_ctl_elem_id id1, id2;
615 int err;
616
617 if (snd_BUG_ON(!chip || !chip->pcm))
618 return -EINVAL;
619
620 card = chip->card;
621
622 strcpy(card->mixername, chip->pcm->name);
623
624 memset(&id1, 0, sizeof(id1));
625 memset(&id2, 0, sizeof(id2));
626 id1.iface = id2.iface = SNDRV_CTL_ELEM_IFACE_MIXER;
627 /* reassign AUX0 switch to CD */
628 strcpy(id1.name, "Aux Playback Switch");
629 strcpy(id2.name, "CD Playback Switch");
630 err = snd_ctl_rename_id(card, &id1, &id2);
631 if (err < 0) {
632 snd_printk(KERN_ERR "Cannot rename opti93x control\n");
633 return err;
634 }
635 /* reassign AUX1 switch to FM */
636 strcpy(id1.name, "Aux Playback Switch"); id1.index = 1;
637 strcpy(id2.name, "FM Playback Switch");
638 err = snd_ctl_rename_id(card, &id1, &id2);
639 if (err < 0) {
640 snd_printk(KERN_ERR "Cannot rename opti93x control\n");
641 return err;
642 }
643 /* remove AUX1 volume */
644 strcpy(id1.name, "Aux Playback Volume"); id1.index = 1;
645 snd_ctl_remove_id(card, &id1);
646
647 /* Replace WSS volume controls with OPTi93x volume controls */
648 id1.index = 0;
649 for (idx = 0; idx < ARRAY_SIZE(snd_opti93x_controls); idx++) {
650 strcpy(id1.name, snd_opti93x_controls[idx].name);
651 snd_ctl_remove_id(card, &id1);
652
653 err = snd_ctl_add(card,
654 snd_ctl_new1(&snd_opti93x_controls[idx], chip));
655 if (err < 0)
656 return err;
657 }
658 return 0;
659}
660
549static irqreturn_t snd_opti93x_interrupt(int irq, void *dev_id) 661static irqreturn_t snd_opti93x_interrupt(int irq, void *dev_id)
550{ 662{
551 struct snd_opti9xx *chip = dev_id; 663 struct snd_opti9xx *chip = dev_id;
@@ -641,15 +753,15 @@ static int __devinit snd_card_opti9xx_pnp(struct snd_opti9xx *chip,
641{ 753{
642 struct pnp_dev *pdev; 754 struct pnp_dev *pdev;
643 int err; 755 int err;
756 struct pnp_dev *devmpu;
757#ifndef OPTi93X
758 struct pnp_dev *devmc;
759#endif
644 760
645 chip->dev = pnp_request_card_device(card, pid->devs[0].id, NULL); 761 pdev = pnp_request_card_device(card, pid->devs[0].id, NULL);
646 if (chip->dev == NULL) 762 if (pdev == NULL)
647 return -EBUSY; 763 return -EBUSY;
648 764
649 chip->devmpu = pnp_request_card_device(card, pid->devs[1].id, NULL);
650
651 pdev = chip->dev;
652
653 err = pnp_activate_dev(pdev); 765 err = pnp_activate_dev(pdev);
654 if (err < 0) { 766 if (err < 0) {
655 snd_printk(KERN_ERR "AUDIO pnp configure failure: %d\n", err); 767 snd_printk(KERN_ERR "AUDIO pnp configure failure: %d\n", err);
@@ -662,9 +774,24 @@ static int __devinit snd_card_opti9xx_pnp(struct snd_opti9xx *chip,
662 chip->mc_indir_index = pnp_port_start(pdev, 3) + 2; 774 chip->mc_indir_index = pnp_port_start(pdev, 3) + 2;
663 chip->mc_indir_size = pnp_port_len(pdev, 3) - 2; 775 chip->mc_indir_size = pnp_port_len(pdev, 3) - 2;
664#else 776#else
665 if (pid->driver_data != 0x0924) 777 devmc = pnp_request_card_device(card, pid->devs[2].id, NULL);
666 port = pnp_port_start(pdev, 1); 778 if (devmc == NULL)
779 return -EBUSY;
780
781 err = pnp_activate_dev(devmc);
782 if (err < 0) {
783 snd_printk(KERN_ERR "MC pnp configure failure: %d\n", err);
784 return err;
785 }
786
787 port = pnp_port_start(pdev, 1);
667 fm_port = pnp_port_start(pdev, 2) + 8; 788 fm_port = pnp_port_start(pdev, 2) + 8;
789 /*
790 * The MC(0) is never accessed and card does not
791 * include it in the PnP resource range. OPTI93x include it.
792 */
793 chip->mc_base = pnp_port_start(devmc, 0) - 1;
794 chip->mc_base_size = pnp_port_len(devmc, 0) + 1;
668#endif /* OPTi93X */ 795#endif /* OPTi93X */
669 irq = pnp_irq(pdev, 0); 796 irq = pnp_irq(pdev, 0);
670 dma1 = pnp_dma(pdev, 0); 797 dma1 = pnp_dma(pdev, 0);
@@ -672,16 +799,16 @@ static int __devinit snd_card_opti9xx_pnp(struct snd_opti9xx *chip,
672 dma2 = pnp_dma(pdev, 1); 799 dma2 = pnp_dma(pdev, 1);
673#endif /* CS4231 || OPTi93X */ 800#endif /* CS4231 || OPTi93X */
674 801
675 pdev = chip->devmpu; 802 devmpu = pnp_request_card_device(card, pid->devs[1].id, NULL);
676 if (pdev && mpu_port > 0) { 803
677 err = pnp_activate_dev(pdev); 804 if (devmpu && mpu_port > 0) {
805 err = pnp_activate_dev(devmpu);
678 if (err < 0) { 806 if (err < 0) {
679 snd_printk(KERN_ERR "AUDIO pnp configure failure\n"); 807 snd_printk(KERN_ERR "MPU401 pnp configure failure\n");
680 mpu_port = -1; 808 mpu_port = -1;
681 chip->devmpu = NULL;
682 } else { 809 } else {
683 mpu_port = pnp_port_start(pdev, 0); 810 mpu_port = pnp_port_start(devmpu, 0);
684 mpu_irq = pnp_irq(pdev, 0); 811 mpu_irq = pnp_irq(devmpu, 0);
685 } 812 }
686 } 813 }
687 return pid->driver_data; 814 return pid->driver_data;
@@ -736,7 +863,7 @@ static int __devinit snd_opti9xx_probe(struct snd_card *card)
736 if (error) 863 if (error)
737 return error; 864 return error;
738 865
739 error = snd_wss_create(card, port + 4, -1, irq, dma1, xdma2, 866 error = snd_wss_create(card, chip->wss_base + 4, -1, irq, dma1, xdma2,
740#ifdef OPTi93X 867#ifdef OPTi93X
741 WSS_HW_OPTI93X, WSS_HWSHARE_IRQ, 868 WSS_HW_OPTI93X, WSS_HWSHARE_IRQ,
742#else 869#else
@@ -754,6 +881,11 @@ static int __devinit snd_opti9xx_probe(struct snd_card *card)
754 error = snd_wss_mixer(codec); 881 error = snd_wss_mixer(codec);
755 if (error < 0) 882 if (error < 0)
756 return error; 883 return error;
884#ifdef OPTi93X
885 error = snd_opti93x_mixer(codec);
886 if (error < 0)
887 return error;
888#endif
757#ifdef CS4231 889#ifdef CS4231
758 error = snd_wss_timer(codec, 0, &timer); 890 error = snd_wss_timer(codec, 0, &timer);
759 if (error < 0) 891 if (error < 0)
@@ -772,10 +904,11 @@ static int __devinit snd_opti9xx_probe(struct snd_card *card)
772 sprintf(card->shortname, "OPTi %s", card->driver); 904 sprintf(card->shortname, "OPTi %s", card->driver);
773#if defined(CS4231) || defined(OPTi93X) 905#if defined(CS4231) || defined(OPTi93X)
774 sprintf(card->longname, "%s, %s at 0x%lx, irq %d, dma %d&%d", 906 sprintf(card->longname, "%s, %s at 0x%lx, irq %d, dma %d&%d",
775 card->shortname, pcm->name, port + 4, irq, dma1, xdma2); 907 card->shortname, pcm->name,
908 chip->wss_base + 4, irq, dma1, xdma2);
776#else 909#else
777 sprintf(card->longname, "%s, %s at 0x%lx, irq %d, dma %d", 910 sprintf(card->longname, "%s, %s at 0x%lx, irq %d, dma %d",
778 card->shortname, pcm->name, port + 4, irq, dma1); 911 card->shortname, pcm->name, chip->wss_base + 4, irq, dma1);
779#endif /* CS4231 || OPTi93X */ 912#endif /* CS4231 || OPTi93X */
780 913
781 if (mpu_port <= 0 || mpu_port == SNDRV_AUTO_PORT) 914 if (mpu_port <= 0 || mpu_port == SNDRV_AUTO_PORT)
@@ -969,9 +1102,6 @@ static int __devinit snd_opti9xx_pnp_probe(struct pnp_card_link *pcard,
969 snd_card_free(card); 1102 snd_card_free(card);
970 return error; 1103 return error;
971 } 1104 }
972 if (hw <= OPTi9XX_HW_82C930)
973 chip->mc_base -= 0x80;
974
975 error = snd_opti9xx_read_check(chip); 1105 error = snd_opti9xx_read_check(chip);
976 if (error) { 1106 if (error) {
977 snd_printk(KERN_ERR "OPTI chip not found\n"); 1107 snd_printk(KERN_ERR "OPTI chip not found\n");