diff options
author | James Courtier-Dutton <James@superbug.co.uk> | 2005-12-04 12:03:03 -0500 |
---|---|---|
committer | Jaroslav Kysela <perex@suse.cz> | 2006-01-03 06:30:15 -0500 |
commit | 19b99fbaed2e2971b756311435c67e84431d8515 (patch) | |
tree | 78f0c968f8bed1a5ce82edd00d793be6f3a73d4c | |
parent | 481ba7727fa08deb389b5a2e550e04df24d3f37d (diff) |
[ALSA] emu10k1: Partial support for Creative emu1212m
Modules: EMU10K1/EMU10K2 driver
Distorted sound now comes from the Audio Out socket. Still more work to do.
Signed-off-by: James Courtier-Dutton <James@superbug.co.uk>
-rw-r--r-- | include/sound/emu10k1.h | 1 | ||||
-rw-r--r-- | sound/pci/emu10k1/emu10k1_main.c | 150 | ||||
-rw-r--r-- | sound/pci/emu10k1/emufx.c | 9 | ||||
-rw-r--r-- | sound/pci/emu10k1/emumixer.c | 4 |
4 files changed, 159 insertions, 5 deletions
diff --git a/include/sound/emu10k1.h b/include/sound/emu10k1.h index 3d0496cc1090..0d6e68c43e63 100644 --- a/include/sound/emu10k1.h +++ b/include/sound/emu10k1.h | |||
@@ -1061,6 +1061,7 @@ struct snd_emu_chip_details { | |||
1061 | unsigned char spdif_bug; /* Has Spdif phasing bug */ | 1061 | unsigned char spdif_bug; /* Has Spdif phasing bug */ |
1062 | unsigned char ac97_chip; /* Has an AC97 chip: 1 = mandatory, 2 = optional */ | 1062 | unsigned char ac97_chip; /* Has an AC97 chip: 1 = mandatory, 2 = optional */ |
1063 | unsigned char ecard; /* APS EEPROM */ | 1063 | unsigned char ecard; /* APS EEPROM */ |
1064 | unsigned char emu1212m; /* EMU 1212m card */ | ||
1064 | const char *driver; | 1065 | const char *driver; |
1065 | const char *name; | 1066 | const char *name; |
1066 | const char *id; /* for backward compatibility - can be NULL if not needed */ | 1067 | const char *id; /* for backward compatibility - can be NULL if not needed */ |
diff --git a/sound/pci/emu10k1/emu10k1_main.c b/sound/pci/emu10k1/emu10k1_main.c index 175f8aac8de5..f6cf589593b9 100644 --- a/sound/pci/emu10k1/emu10k1_main.c +++ b/sound/pci/emu10k1/emu10k1_main.c | |||
@@ -42,6 +42,7 @@ | |||
42 | #include "p16v.h" | 42 | #include "p16v.h" |
43 | #include "tina2.h" | 43 | #include "tina2.h" |
44 | 44 | ||
45 | |||
45 | /************************************************************************* | 46 | /************************************************************************* |
46 | * EMU10K1 init / done | 47 | * EMU10K1 init / done |
47 | *************************************************************************/ | 48 | *************************************************************************/ |
@@ -217,7 +218,9 @@ static int snd_emu10k1_init(struct snd_emu10k1 *emu, int enable_ir, int resume) | |||
217 | outl(HCFG_LOCKTANKCACHE_MASK | HCFG_AUTOMUTE | HCFG_JOYENABLE, emu->port + HCFG); | 218 | outl(HCFG_LOCKTANKCACHE_MASK | HCFG_AUTOMUTE | HCFG_JOYENABLE, emu->port + HCFG); |
218 | 219 | ||
219 | if (enable_ir) { /* enable IR for SB Live */ | 220 | if (enable_ir) { /* enable IR for SB Live */ |
220 | if (emu->audigy) { | 221 | if ( emu->card_capabilities->emu1212m) { |
222 | ; /* Disable all access to A_IOCFG for the emu1212m */ | ||
223 | } else if (emu->audigy) { | ||
221 | unsigned int reg = inl(emu->port + A_IOCFG); | 224 | unsigned int reg = inl(emu->port + A_IOCFG); |
222 | outl(reg | A_IOCFG_GPOUT2, emu->port + A_IOCFG); | 225 | outl(reg | A_IOCFG_GPOUT2, emu->port + A_IOCFG); |
223 | udelay(500); | 226 | udelay(500); |
@@ -234,7 +237,9 @@ static int snd_emu10k1_init(struct snd_emu10k1 *emu, int enable_ir, int resume) | |||
234 | } | 237 | } |
235 | } | 238 | } |
236 | 239 | ||
237 | if (emu->audigy) { /* enable analog output */ | 240 | if ( emu->card_capabilities->emu1212m) { |
241 | ; /* Disable all access to A_IOCFG for the emu1212m */ | ||
242 | } else if (emu->audigy) { /* enable analog output */ | ||
238 | unsigned int reg = inl(emu->port + A_IOCFG); | 243 | unsigned int reg = inl(emu->port + A_IOCFG); |
239 | outl(reg | A_IOCFG_GPOUT0, emu->port + A_IOCFG); | 244 | outl(reg | A_IOCFG_GPOUT0, emu->port + A_IOCFG); |
240 | } | 245 | } |
@@ -250,7 +255,9 @@ static void snd_emu10k1_audio_enable(struct snd_emu10k1 *emu) | |||
250 | outl(inl(emu->port + HCFG) | HCFG_AUDIOENABLE, emu->port + HCFG); | 255 | outl(inl(emu->port + HCFG) | HCFG_AUDIOENABLE, emu->port + HCFG); |
251 | 256 | ||
252 | /* Enable analog/digital outs on audigy */ | 257 | /* Enable analog/digital outs on audigy */ |
253 | if (emu->audigy) { | 258 | if ( emu->card_capabilities->emu1212m) { |
259 | ; /* Disable all access to A_IOCFG for the emu1212m */ | ||
260 | } else if (emu->audigy) { | ||
254 | outl(inl(emu->port + A_IOCFG) & ~0x44, emu->port + A_IOCFG); | 261 | outl(inl(emu->port + A_IOCFG) & ~0x44, emu->port + A_IOCFG); |
255 | 262 | ||
256 | if (emu->card_capabilities->ca0151_chip) { /* audigy2 */ | 263 | if (emu->card_capabilities->ca0151_chip) { /* audigy2 */ |
@@ -542,6 +549,136 @@ static int __devinit snd_emu10k1_cardbus_init(struct snd_emu10k1 * emu) | |||
542 | return 0; | 549 | return 0; |
543 | } | 550 | } |
544 | 551 | ||
552 | static int snd_emu1212m_fpga_write(struct snd_emu10k1 * emu, int reg, int value) | ||
553 | { | ||
554 | if (reg<0 || reg>0x3f) | ||
555 | return 1; | ||
556 | reg+=0x40; /* 0x40 upwards are registers. */ | ||
557 | if (value<0 || value>0x3f) /* 0 to 0x3f are values */ | ||
558 | return 1; | ||
559 | outl(reg, emu->port + A_IOCFG); | ||
560 | outl(reg | 0x80, emu->port + A_IOCFG); /* High bit clocks the value into the fpga. */ | ||
561 | outl(value, emu->port + A_IOCFG); | ||
562 | outl(value | 0x80 , emu->port + A_IOCFG); /* High bit clocks the value into the fpga. */ | ||
563 | |||
564 | return 0; | ||
565 | } | ||
566 | |||
567 | static int snd_emu1212m_fpga_read(struct snd_emu10k1 * emu, int reg, int *value) | ||
568 | { | ||
569 | if (reg<0 || reg>0x3f) | ||
570 | return 1; | ||
571 | reg+=0x40; /* 0x40 upwards are registers. */ | ||
572 | outl(reg, emu->port + A_IOCFG); | ||
573 | outl(reg | 0x80, emu->port + A_IOCFG); /* High bit clocks the value into the fpga. */ | ||
574 | *value = inl(emu->port + A_IOCFG); | ||
575 | |||
576 | return 0; | ||
577 | } | ||
578 | |||
579 | static int snd_emu1212m_fpga_netlist_write(struct snd_emu10k1 * emu, int reg, int value) | ||
580 | { | ||
581 | snd_emu1212m_fpga_write(emu, 0x00, ((reg >> 8) & 0x3f) ); | ||
582 | snd_emu1212m_fpga_write(emu, 0x01, (reg & 0x3f) ); | ||
583 | snd_emu1212m_fpga_write(emu, 0x02, ((value >> 8) & 0x3f) ); | ||
584 | snd_emu1212m_fpga_write(emu, 0x03, (value & 0x3f) ); | ||
585 | |||
586 | return 0; | ||
587 | } | ||
588 | |||
589 | static int __devinit snd_emu10k1_emu1212m_init(struct snd_emu10k1 * emu) | ||
590 | { | ||
591 | unsigned int i; | ||
592 | int tmp; | ||
593 | |||
594 | snd_printk(KERN_ERR "emu1212m: Special config.\n"); | ||
595 | outl(0x0005a00c, emu->port + HCFG); | ||
596 | outl(0x0005a004, emu->port + HCFG); | ||
597 | outl(0x0005a000, emu->port + HCFG); | ||
598 | outl(0x0005a000, emu->port + HCFG); | ||
599 | |||
600 | snd_emu1212m_fpga_read(emu, 0x22, &tmp ); | ||
601 | snd_emu1212m_fpga_read(emu, 0x23, &tmp ); | ||
602 | snd_emu1212m_fpga_read(emu, 0x24, &tmp ); | ||
603 | snd_emu1212m_fpga_write(emu, 0x04, 0x01 ); | ||
604 | snd_emu1212m_fpga_read(emu, 0x0b, &tmp ); | ||
605 | snd_emu1212m_fpga_write(emu, 0x0b, 0x01 ); | ||
606 | snd_emu1212m_fpga_read(emu, 0x10, &tmp ); | ||
607 | snd_emu1212m_fpga_write(emu, 0x10, 0x00 ); | ||
608 | snd_emu1212m_fpga_read(emu, 0x11, &tmp ); | ||
609 | snd_emu1212m_fpga_write(emu, 0x11, 0x30 ); | ||
610 | snd_emu1212m_fpga_read(emu, 0x13, &tmp ); | ||
611 | snd_emu1212m_fpga_write(emu, 0x13, 0x0f ); | ||
612 | snd_emu1212m_fpga_read(emu, 0x11, &tmp ); | ||
613 | snd_emu1212m_fpga_write(emu, 0x11, 0x30 ); | ||
614 | snd_emu1212m_fpga_read(emu, 0x0a, &tmp ); | ||
615 | snd_emu1212m_fpga_write(emu, 0x0a, 0x10 ); | ||
616 | snd_emu1212m_fpga_write(emu, 0x0c, 0x19 ); | ||
617 | snd_emu1212m_fpga_write(emu, 0x12, 0x0c ); | ||
618 | snd_emu1212m_fpga_write(emu, 0x09, 0x0f ); | ||
619 | snd_emu1212m_fpga_write(emu, 0x06, 0x00 ); | ||
620 | snd_emu1212m_fpga_write(emu, 0x05, 0x00 ); | ||
621 | snd_emu1212m_fpga_write(emu, 0x0e, 0x12 ); | ||
622 | snd_emu1212m_fpga_netlist_write(emu, 0x0000, 0x0200); | ||
623 | snd_emu1212m_fpga_netlist_write(emu, 0x0001, 0x0201); | ||
624 | snd_emu1212m_fpga_netlist_write(emu, 0x0002, 0x0500); | ||
625 | snd_emu1212m_fpga_netlist_write(emu, 0x0003, 0x0501); | ||
626 | snd_emu1212m_fpga_netlist_write(emu, 0x0004, 0x0400); | ||
627 | snd_emu1212m_fpga_netlist_write(emu, 0x0005, 0x0401); | ||
628 | snd_emu1212m_fpga_netlist_write(emu, 0x0006, 0x0402); | ||
629 | snd_emu1212m_fpga_netlist_write(emu, 0x0007, 0x0403); | ||
630 | snd_emu1212m_fpga_netlist_write(emu, 0x0008, 0x0404); | ||
631 | snd_emu1212m_fpga_netlist_write(emu, 0x0009, 0x0405); | ||
632 | snd_emu1212m_fpga_netlist_write(emu, 0x000a, 0x0406); | ||
633 | snd_emu1212m_fpga_netlist_write(emu, 0x000b, 0x0407); | ||
634 | snd_emu1212m_fpga_netlist_write(emu, 0x000c, 0x0100); | ||
635 | snd_emu1212m_fpga_netlist_write(emu, 0x000d, 0x0104); | ||
636 | snd_emu1212m_fpga_netlist_write(emu, 0x000e, 0x0200); | ||
637 | snd_emu1212m_fpga_netlist_write(emu, 0x000f, 0x0201); | ||
638 | for (i=0;i < 0x20;i++) { | ||
639 | snd_emu1212m_fpga_netlist_write(emu, 0x0100+i, 0x0000); | ||
640 | } | ||
641 | for (i=0;i < 4;i++) { | ||
642 | snd_emu1212m_fpga_netlist_write(emu, 0x0200+i, 0x0000); | ||
643 | } | ||
644 | for (i=0;i < 7;i++) { | ||
645 | snd_emu1212m_fpga_netlist_write(emu, 0x0300+i, 0x0000); | ||
646 | } | ||
647 | for (i=0;i < 7;i++) { | ||
648 | snd_emu1212m_fpga_netlist_write(emu, 0x0400+i, 0x0000); | ||
649 | } | ||
650 | snd_emu1212m_fpga_netlist_write(emu, 0x0500, 0x0108); | ||
651 | snd_emu1212m_fpga_netlist_write(emu, 0x0501, 0x010c); | ||
652 | snd_emu1212m_fpga_netlist_write(emu, 0x0600, 0x0110); | ||
653 | snd_emu1212m_fpga_netlist_write(emu, 0x0601, 0x0114); | ||
654 | snd_emu1212m_fpga_netlist_write(emu, 0x0700, 0x0118); | ||
655 | snd_emu1212m_fpga_netlist_write(emu, 0x0701, 0x011c); | ||
656 | snd_emu1212m_fpga_write(emu, 0x07, 0x01 ); | ||
657 | |||
658 | snd_emu1212m_fpga_read(emu, 0x21, &tmp ); | ||
659 | |||
660 | outl(0x0000a000, emu->port + HCFG); | ||
661 | outl(0x0000a001, emu->port + HCFG); | ||
662 | /* Initial boot complete. Now patches */ | ||
663 | |||
664 | snd_emu1212m_fpga_read(emu, 0x21, &tmp ); | ||
665 | snd_emu1212m_fpga_write(emu, 0x0c, 0x19 ); | ||
666 | snd_emu1212m_fpga_write(emu, 0x12, 0x0c ); | ||
667 | snd_emu1212m_fpga_write(emu, 0x0c, 0x19 ); | ||
668 | snd_emu1212m_fpga_write(emu, 0x12, 0x0c ); | ||
669 | snd_emu1212m_fpga_read(emu, 0x0a, &tmp ); | ||
670 | snd_emu1212m_fpga_write(emu, 0x0a, 0x10 ); | ||
671 | |||
672 | snd_emu1212m_fpga_read(emu, 0x20, &tmp ); | ||
673 | snd_emu1212m_fpga_read(emu, 0x21, &tmp ); | ||
674 | |||
675 | snd_emu1212m_fpga_netlist_write(emu, 0x0300, 0x0312); | ||
676 | snd_emu1212m_fpga_netlist_write(emu, 0x0301, 0x0313); | ||
677 | snd_emu1212m_fpga_netlist_write(emu, 0x0200, 0x0302); | ||
678 | snd_emu1212m_fpga_netlist_write(emu, 0x0201, 0x0303); | ||
679 | |||
680 | return 0; | ||
681 | } | ||
545 | /* | 682 | /* |
546 | * Create the EMU10K1 instance | 683 | * Create the EMU10K1 instance |
547 | */ | 684 | */ |
@@ -623,7 +760,7 @@ static struct snd_emu_chip_details emu_chip_details[] = { | |||
623 | .id = "EMU1212m", | 760 | .id = "EMU1212m", |
624 | .emu10k2_chip = 1, | 761 | .emu10k2_chip = 1, |
625 | .ca0102_chip = 1, | 762 | .ca0102_chip = 1, |
626 | .ecard = 1} , | 763 | .emu1212m = 1} , |
627 | /* Tested by James@superbug.co.uk 3rd July 2005 */ | 764 | /* Tested by James@superbug.co.uk 3rd July 2005 */ |
628 | {.vendor = 0x1102, .device = 0x0004, .subsystem = 0x20071102, | 765 | {.vendor = 0x1102, .device = 0x0004, .subsystem = 0x20071102, |
629 | .driver = "Audigy2", .name = "Audigy 4 PRO [SB0380]", | 766 | .driver = "Audigy2", .name = "Audigy 4 PRO [SB0380]", |
@@ -1013,6 +1150,11 @@ int __devinit snd_emu10k1_create(struct snd_card *card, | |||
1013 | } else if (emu->card_capabilities->ca_cardbus_chip) { | 1150 | } else if (emu->card_capabilities->ca_cardbus_chip) { |
1014 | if ((err = snd_emu10k1_cardbus_init(emu)) < 0) | 1151 | if ((err = snd_emu10k1_cardbus_init(emu)) < 0) |
1015 | goto error; | 1152 | goto error; |
1153 | } else if (emu->card_capabilities->emu1212m) { | ||
1154 | if ((err = snd_emu10k1_emu1212m_init(emu)) < 0) { | ||
1155 | snd_emu10k1_free(emu); | ||
1156 | return err; | ||
1157 | } | ||
1016 | } else { | 1158 | } else { |
1017 | /* 5.1: Enable the additional AC97 Slots. If the emu10k1 version | 1159 | /* 5.1: Enable the additional AC97 Slots. If the emu10k1 version |
1018 | does not support this, it shouldn't do any harm */ | 1160 | does not support this, it shouldn't do any harm */ |
diff --git a/sound/pci/emu10k1/emufx.c b/sound/pci/emu10k1/emufx.c index a44e4fdfc025..cd356b04078b 100644 --- a/sound/pci/emu10k1/emufx.c +++ b/sound/pci/emu10k1/emufx.c | |||
@@ -1102,6 +1102,14 @@ static int __devinit _snd_emu10k1_audigy_init_efx(struct snd_emu10k1 *emu) | |||
1102 | /* stop FX processor */ | 1102 | /* stop FX processor */ |
1103 | snd_emu10k1_ptr_write(emu, A_DBG, 0, (emu->fx8010.dbg = 0) | A_DBG_SINGLE_STEP); | 1103 | snd_emu10k1_ptr_write(emu, A_DBG, 0, (emu->fx8010.dbg = 0) | A_DBG_SINGLE_STEP); |
1104 | 1104 | ||
1105 | #if 0 | ||
1106 | /* FIX: jcd test */ | ||
1107 | for (z = 0; z < 80; z=z+2) { | ||
1108 | A_OP(icode, &ptr, iACC3, A_EXTOUT(z), A_FXBUS(FXBUS_PCM_LEFT_FRONT), A_C_00000000, A_C_00000000); /* left */ | ||
1109 | A_OP(icode, &ptr, iACC3, A_EXTOUT(z+1), A_FXBUS(FXBUS_PCM_RIGHT_FRONT), A_C_00000000, A_C_00000000); /* right */ | ||
1110 | } | ||
1111 | #endif /* jcd test */ | ||
1112 | #if 1 | ||
1105 | /* PCM front Playback Volume (independent from stereo mix) */ | 1113 | /* PCM front Playback Volume (independent from stereo mix) */ |
1106 | A_OP(icode, &ptr, iMAC0, A_GPR(playback), A_C_00000000, A_GPR(gpr), A_FXBUS(FXBUS_PCM_LEFT_FRONT)); | 1114 | A_OP(icode, &ptr, iMAC0, A_GPR(playback), A_C_00000000, A_GPR(gpr), A_FXBUS(FXBUS_PCM_LEFT_FRONT)); |
1107 | A_OP(icode, &ptr, iMAC0, A_GPR(playback+1), A_C_00000000, A_GPR(gpr+1), A_FXBUS(FXBUS_PCM_RIGHT_FRONT)); | 1115 | A_OP(icode, &ptr, iMAC0, A_GPR(playback+1), A_C_00000000, A_GPR(gpr+1), A_FXBUS(FXBUS_PCM_RIGHT_FRONT)); |
@@ -1447,6 +1455,7 @@ A_OP(icode, &ptr, iMAC0, A_GPR(var), A_GPR(var), A_GPR(vol), A_EXTIN(input)) | |||
1447 | A_OP(icode, &ptr, iACC3, A_FXBUS2(z), A_C_00000000, A_C_00000000, A_EXTIN(z)); | 1455 | A_OP(icode, &ptr, iACC3, A_FXBUS2(z), A_C_00000000, A_C_00000000, A_EXTIN(z)); |
1448 | } | 1456 | } |
1449 | 1457 | ||
1458 | #endif /* JCD test */ | ||
1450 | /* | 1459 | /* |
1451 | * ok, set up done.. | 1460 | * ok, set up done.. |
1452 | */ | 1461 | */ |
diff --git a/sound/pci/emu10k1/emumixer.c b/sound/pci/emu10k1/emumixer.c index 98fb8139427b..306fe4aa4aa5 100644 --- a/sound/pci/emu10k1/emumixer.c +++ b/sound/pci/emu10k1/emumixer.c | |||
@@ -959,7 +959,9 @@ int __devinit snd_emu10k1_mixer(struct snd_emu10k1 *emu, | |||
959 | return err; | 959 | return err; |
960 | } | 960 | } |
961 | 961 | ||
962 | if (emu->audigy) { | 962 | if ( emu->card_capabilities->emu1212m) { |
963 | ; /* Disable the snd_audigy_spdif_shared_spdif */ | ||
964 | } else if (emu->audigy) { | ||
963 | if ((kctl = snd_ctl_new1(&snd_audigy_shared_spdif, emu)) == NULL) | 965 | if ((kctl = snd_ctl_new1(&snd_audigy_shared_spdif, emu)) == NULL) |
964 | return -ENOMEM; | 966 | return -ENOMEM; |
965 | if ((err = snd_ctl_add(card, kctl))) | 967 | if ((err = snd_ctl_add(card, kctl))) |