aboutsummaryrefslogtreecommitdiffstats
path: root/sound/pci/emu10k1/emu10k1_main.c
diff options
context:
space:
mode:
authorJames Courtier-Dutton <James@superbug.co.uk>2005-12-04 12:03:03 -0500
committerJaroslav Kysela <perex@suse.cz>2006-01-03 06:30:15 -0500
commit19b99fbaed2e2971b756311435c67e84431d8515 (patch)
tree78f0c968f8bed1a5ce82edd00d793be6f3a73d4c /sound/pci/emu10k1/emu10k1_main.c
parent481ba7727fa08deb389b5a2e550e04df24d3f37d (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>
Diffstat (limited to 'sound/pci/emu10k1/emu10k1_main.c')
-rw-r--r--sound/pci/emu10k1/emu10k1_main.c150
1 files changed, 146 insertions, 4 deletions
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
552static 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
567static 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
579static 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
589static 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 */