diff options
author | James Courtier-Dutton <James@superbug.co.uk> | 2006-10-01 05:48:04 -0400 |
---|---|---|
committer | Jaroslav Kysela <perex@suse.cz> | 2007-02-09 02:59:59 -0500 |
commit | 9f4bd5dde81b5cb94e4f52f2f05825aa0422f1ff (patch) | |
tree | 884d0016c361a555ab1bc95287e64a6c109a0609 /sound | |
parent | 5986a2ec35836a878350c54af4bd91b1de6abc59 (diff) |
[ALSA] snd-emu10k1: Added support for emu1010, including E-Mu 1212m and E-Mu 1820m
Signed-off-by: James Courtier-Dutton <James@superbug.co.uk>
Signed-off-by: Jaroslav Kysela <perex@suse.cz>
Diffstat (limited to 'sound')
-rw-r--r-- | sound/pci/emu10k1/emu10k1_main.c | 540 | ||||
-rw-r--r-- | sound/pci/emu10k1/emu10k1x.c | 6 | ||||
-rw-r--r-- | sound/pci/emu10k1/emufx.c | 102 | ||||
-rw-r--r-- | sound/pci/emu10k1/emumixer.c | 325 | ||||
-rw-r--r-- | sound/pci/emu10k1/emupcm.c | 127 | ||||
-rw-r--r-- | sound/pci/emu10k1/emuproc.c | 34 | ||||
-rw-r--r-- | sound/pci/emu10k1/io.c | 45 | ||||
-rw-r--r-- | sound/pci/emu10k1/p16v.c | 12 | ||||
-rw-r--r-- | sound/pci/emu10k1/voice.c | 2 |
9 files changed, 1015 insertions, 178 deletions
diff --git a/sound/pci/emu10k1/emu10k1_main.c b/sound/pci/emu10k1/emu10k1_main.c index 972ec40d8166..891172f2b1d7 100644 --- a/sound/pci/emu10k1/emu10k1_main.c +++ b/sound/pci/emu10k1/emu10k1_main.c | |||
@@ -3,8 +3,10 @@ | |||
3 | * Creative Labs, Inc. | 3 | * Creative Labs, Inc. |
4 | * Routines for control of EMU10K1 chips | 4 | * Routines for control of EMU10K1 chips |
5 | * | 5 | * |
6 | * Copyright (c) by James Courtier-Dutton <James@superbug.demon.co.uk> | 6 | * Copyright (c) by James Courtier-Dutton <James@superbug.co.uk> |
7 | * Added support for Audigy 2 Value. | 7 | * Added support for Audigy 2 Value. |
8 | * Added EMU 1010 support. | ||
9 | * General bug fixes and enhancements. | ||
8 | * | 10 | * |
9 | * | 11 | * |
10 | * BUGS: | 12 | * BUGS: |
@@ -41,6 +43,7 @@ | |||
41 | 43 | ||
42 | #include <sound/core.h> | 44 | #include <sound/core.h> |
43 | #include <sound/emu10k1.h> | 45 | #include <sound/emu10k1.h> |
46 | #include <linux/firmware.h> | ||
44 | #include "p16v.h" | 47 | #include "p16v.h" |
45 | #include "tina2.h" | 48 | #include "tina2.h" |
46 | 49 | ||
@@ -211,7 +214,7 @@ static int snd_emu10k1_init(struct snd_emu10k1 *emu, int enable_ir, int resume) | |||
211 | int size, n; | 214 | int size, n; |
212 | 215 | ||
213 | size = ARRAY_SIZE(spi_dac_init); | 216 | size = ARRAY_SIZE(spi_dac_init); |
214 | for (n=0; n < size; n++) | 217 | for (n = 0; n < size; n++) |
215 | snd_emu10k1_spi_write(emu, spi_dac_init[n]); | 218 | snd_emu10k1_spi_write(emu, spi_dac_init[n]); |
216 | 219 | ||
217 | snd_emu10k1_ptr20_write(emu, 0x60, 0, 0x10); | 220 | snd_emu10k1_ptr20_write(emu, 0x60, 0, 0x10); |
@@ -239,6 +242,10 @@ static int snd_emu10k1_init(struct snd_emu10k1 *emu, int enable_ir, int resume) | |||
239 | snd_emu10k1_ptr_write(emu, MAPB, ch, silent_page); | 242 | snd_emu10k1_ptr_write(emu, MAPB, ch, silent_page); |
240 | } | 243 | } |
241 | 244 | ||
245 | if (emu->card_capabilities->emu1010) { | ||
246 | outl(HCFG_AUTOMUTE_ASYNC | | ||
247 | HCFG_EMU32_SLAVE | | ||
248 | HCFG_AUDIOENABLE, emu->port + HCFG); | ||
242 | /* | 249 | /* |
243 | * Hokay, setup HCFG | 250 | * Hokay, setup HCFG |
244 | * Mute Disable Audio = 0 | 251 | * Mute Disable Audio = 0 |
@@ -246,7 +253,7 @@ static int snd_emu10k1_init(struct snd_emu10k1 *emu, int enable_ir, int resume) | |||
246 | * Lock Sound Memory = 0 | 253 | * Lock Sound Memory = 0 |
247 | * Auto Mute = 1 | 254 | * Auto Mute = 1 |
248 | */ | 255 | */ |
249 | if (emu->audigy) { | 256 | } else if (emu->audigy) { |
250 | if (emu->revision == 4) /* audigy2 */ | 257 | if (emu->revision == 4) /* audigy2 */ |
251 | outl(HCFG_AUDIOENABLE | | 258 | outl(HCFG_AUDIOENABLE | |
252 | HCFG_AC3ENABLE_CDSPDIF | | 259 | HCFG_AC3ENABLE_CDSPDIF | |
@@ -265,8 +272,8 @@ static int snd_emu10k1_init(struct snd_emu10k1 *emu, int enable_ir, int resume) | |||
265 | outl(HCFG_LOCKTANKCACHE_MASK | HCFG_AUTOMUTE | HCFG_JOYENABLE, emu->port + HCFG); | 272 | outl(HCFG_LOCKTANKCACHE_MASK | HCFG_AUTOMUTE | HCFG_JOYENABLE, emu->port + HCFG); |
266 | 273 | ||
267 | if (enable_ir) { /* enable IR for SB Live */ | 274 | if (enable_ir) { /* enable IR for SB Live */ |
268 | if ( emu->card_capabilities->emu1212m) { | 275 | if (emu->card_capabilities->emu1010) { |
269 | ; /* Disable all access to A_IOCFG for the emu1212m */ | 276 | ; /* Disable all access to A_IOCFG for the emu1010 */ |
270 | } else if (emu->audigy) { | 277 | } else if (emu->audigy) { |
271 | unsigned int reg = inl(emu->port + A_IOCFG); | 278 | unsigned int reg = inl(emu->port + A_IOCFG); |
272 | outl(reg | A_IOCFG_GPOUT2, emu->port + A_IOCFG); | 279 | outl(reg | A_IOCFG_GPOUT2, emu->port + A_IOCFG); |
@@ -284,8 +291,8 @@ static int snd_emu10k1_init(struct snd_emu10k1 *emu, int enable_ir, int resume) | |||
284 | } | 291 | } |
285 | } | 292 | } |
286 | 293 | ||
287 | if ( emu->card_capabilities->emu1212m) { | 294 | if (emu->card_capabilities->emu1010) { |
288 | ; /* Disable all access to A_IOCFG for the emu1212m */ | 295 | ; /* Disable all access to A_IOCFG for the emu1010 */ |
289 | } else if (emu->audigy) { /* enable analog output */ | 296 | } else if (emu->audigy) { /* enable analog output */ |
290 | unsigned int reg = inl(emu->port + A_IOCFG); | 297 | unsigned int reg = inl(emu->port + A_IOCFG); |
291 | outl(reg | A_IOCFG_GPOUT0, emu->port + A_IOCFG); | 298 | outl(reg | A_IOCFG_GPOUT0, emu->port + A_IOCFG); |
@@ -302,8 +309,8 @@ static void snd_emu10k1_audio_enable(struct snd_emu10k1 *emu) | |||
302 | outl(inl(emu->port + HCFG) | HCFG_AUDIOENABLE, emu->port + HCFG); | 309 | outl(inl(emu->port + HCFG) | HCFG_AUDIOENABLE, emu->port + HCFG); |
303 | 310 | ||
304 | /* Enable analog/digital outs on audigy */ | 311 | /* Enable analog/digital outs on audigy */ |
305 | if ( emu->card_capabilities->emu1212m) { | 312 | if (emu->card_capabilities->emu1010) { |
306 | ; /* Disable all access to A_IOCFG for the emu1212m */ | 313 | ; /* Disable all access to A_IOCFG for the emu1010 */ |
307 | } else if (emu->audigy) { | 314 | } else if (emu->audigy) { |
308 | outl(inl(emu->port + A_IOCFG) & ~0x44, emu->port + A_IOCFG); | 315 | outl(inl(emu->port + A_IOCFG) & ~0x44, emu->port + A_IOCFG); |
309 | 316 | ||
@@ -596,133 +603,417 @@ static int snd_emu10k1_cardbus_init(struct snd_emu10k1 * emu) | |||
596 | return 0; | 603 | return 0; |
597 | } | 604 | } |
598 | 605 | ||
599 | static int snd_emu1212m_fpga_write(struct snd_emu10k1 * emu, int reg, int value) | 606 | static int snd_emu1010_load_firmware(struct snd_emu10k1 * emu, const char * filename) |
600 | { | ||
601 | if (reg<0 || reg>0x3f) | ||
602 | return 1; | ||
603 | reg+=0x40; /* 0x40 upwards are registers. */ | ||
604 | if (value<0 || value>0x3f) /* 0 to 0x3f are values */ | ||
605 | return 1; | ||
606 | outl(reg, emu->port + A_IOCFG); | ||
607 | outl(reg | 0x80, emu->port + A_IOCFG); /* High bit clocks the value into the fpga. */ | ||
608 | outl(value, emu->port + A_IOCFG); | ||
609 | outl(value | 0x80 , emu->port + A_IOCFG); /* High bit clocks the value into the fpga. */ | ||
610 | |||
611 | return 0; | ||
612 | } | ||
613 | |||
614 | static int snd_emu1212m_fpga_read(struct snd_emu10k1 * emu, int reg, int *value) | ||
615 | { | 607 | { |
616 | if (reg<0 || reg>0x3f) | 608 | int err; |
617 | return 1; | 609 | int n, i; |
618 | reg+=0x40; /* 0x40 upwards are registers. */ | 610 | int reg; |
619 | outl(reg, emu->port + A_IOCFG); | 611 | int value; |
620 | outl(reg | 0x80, emu->port + A_IOCFG); /* High bit clocks the value into the fpga. */ | 612 | const struct firmware *fw_entry; |
621 | *value = inl(emu->port + A_IOCFG); | 613 | |
622 | 614 | if ((err = request_firmware(&fw_entry, filename, &emu->pci->dev)) != 0) { | |
623 | return 0; | 615 | snd_printk(KERN_ERR "firmware: %s not found. Err=%d\n",filename, err); |
624 | } | 616 | return err; |
617 | } | ||
618 | snd_printk(KERN_INFO "firmware size=0x%x\n",fw_entry->size); | ||
619 | if (fw_entry->size != 0x133a4) { | ||
620 | snd_printk(KERN_ERR "firmware: %s wrong size.\n",filename); | ||
621 | return -EINVAL; | ||
622 | } | ||
625 | 623 | ||
626 | static int snd_emu1212m_fpga_netlist_write(struct snd_emu10k1 * emu, int reg, int value) | 624 | /* The FPGA is a Xilinx Spartan IIE XC2S50E */ |
627 | { | 625 | /* GPIO7 -> FPGA PGMN |
628 | snd_emu1212m_fpga_write(emu, 0x00, ((reg >> 8) & 0x3f) ); | 626 | * GPIO6 -> FPGA CCLK |
629 | snd_emu1212m_fpga_write(emu, 0x01, (reg & 0x3f) ); | 627 | * GPIO5 -> FPGA DIN |
630 | snd_emu1212m_fpga_write(emu, 0x02, ((value >> 8) & 0x3f) ); | 628 | * FPGA CONFIG OFF -> FPGA PGMN |
631 | snd_emu1212m_fpga_write(emu, 0x03, (value & 0x3f) ); | 629 | */ |
630 | outl(0x00, emu->port + A_IOCFG); /* Set PGMN low for 1uS. */ | ||
631 | udelay(1); | ||
632 | outl(0x80, emu->port + A_IOCFG); /* Leave bit 7 set during netlist setup. */ | ||
633 | udelay(100); /* Allow FPGA memory to clean */ | ||
634 | for(n = 0; n < fw_entry->size; n++) { | ||
635 | value=fw_entry->data[n]; | ||
636 | for(i = 0; i < 8; i++) { | ||
637 | reg = 0x80; | ||
638 | if (value & 0x1) | ||
639 | reg = reg | 0x20; | ||
640 | value = value >> 1; | ||
641 | outl(reg, emu->port + A_IOCFG); | ||
642 | outl(reg | 0x40, emu->port + A_IOCFG); | ||
643 | } | ||
644 | } | ||
645 | /* After programming, set GPIO bit 4 high again. */ | ||
646 | outl(0x10, emu->port + A_IOCFG); | ||
647 | |||
632 | 648 | ||
649 | release_firmware(fw_entry); | ||
633 | return 0; | 650 | return 0; |
634 | } | 651 | } |
635 | 652 | ||
636 | static int snd_emu10k1_emu1212m_init(struct snd_emu10k1 * emu) | 653 | static int snd_emu10k1_emu1010_init(struct snd_emu10k1 * emu) |
637 | { | 654 | { |
638 | unsigned int i; | 655 | unsigned int i; |
639 | int tmp; | 656 | int tmp,tmp2; |
640 | 657 | int reg; | |
641 | snd_printk(KERN_ERR "emu1212m: Special config.\n"); | 658 | int err; |
659 | const char *hana_filename = "emu/hana.fw"; | ||
660 | const char *dock_filename = "emu/audio_dock.fw"; | ||
661 | |||
662 | snd_printk(KERN_INFO "emu1010: Special config.\n"); | ||
663 | /* AC97 2.1, Any 16Meg of 4Gig address, Auto-Mute, EMU32 Slave, | ||
664 | * Lock Sound Memory Cache, Lock Tank Memory Cache, | ||
665 | * Mute all codecs. | ||
666 | */ | ||
642 | outl(0x0005a00c, emu->port + HCFG); | 667 | outl(0x0005a00c, emu->port + HCFG); |
643 | outl(0x0005a004, emu->port + HCFG); | 668 | /* AC97 2.1, Any 16Meg of 4Gig address, Auto-Mute, EMU32 Slave, |
669 | * Lock Tank Memory Cache, | ||
670 | * Mute all codecs. | ||
671 | */ | ||
672 | outl(0x0005a004, emu->port + HCFG); | ||
673 | /* AC97 2.1, Any 16Meg of 4Gig address, Auto-Mute, EMU32 Slave, | ||
674 | * Mute all codecs. | ||
675 | */ | ||
644 | outl(0x0005a000, emu->port + HCFG); | 676 | outl(0x0005a000, emu->port + HCFG); |
677 | /* AC97 2.1, Any 16Meg of 4Gig address, Auto-Mute, EMU32 Slave, | ||
678 | * Mute all codecs. | ||
679 | */ | ||
645 | outl(0x0005a000, emu->port + HCFG); | 680 | outl(0x0005a000, emu->port + HCFG); |
646 | 681 | ||
647 | snd_emu1212m_fpga_read(emu, 0x22, &tmp ); | 682 | /* Disable 48Volt power to Audio Dock */ |
648 | snd_emu1212m_fpga_read(emu, 0x23, &tmp ); | 683 | snd_emu1010_fpga_write(emu, EMU_HANA_DOCK_PWR, 0 ); |
649 | snd_emu1212m_fpga_read(emu, 0x24, &tmp ); | 684 | |
650 | snd_emu1212m_fpga_write(emu, 0x04, 0x01 ); | 685 | /* ID, should read & 0x7f = 0x55. (Bit 7 is the IRQ bit) */ |
651 | snd_emu1212m_fpga_read(emu, 0x0b, &tmp ); | 686 | snd_emu1010_fpga_read(emu, EMU_HANA_ID, ® ); |
652 | snd_emu1212m_fpga_write(emu, 0x0b, 0x01 ); | 687 | snd_printdd("reg1=0x%x\n",reg); |
653 | snd_emu1212m_fpga_read(emu, 0x10, &tmp ); | 688 | if (reg == 0x55) { |
654 | snd_emu1212m_fpga_write(emu, 0x10, 0x00 ); | 689 | /* FPGA netlist already present so clear it */ |
655 | snd_emu1212m_fpga_read(emu, 0x11, &tmp ); | 690 | /* Return to programming mode */ |
656 | snd_emu1212m_fpga_write(emu, 0x11, 0x30 ); | 691 | |
657 | snd_emu1212m_fpga_read(emu, 0x13, &tmp ); | 692 | snd_emu1010_fpga_write(emu, EMU_HANA_FPGA_CONFIG, 0x02 ); |
658 | snd_emu1212m_fpga_write(emu, 0x13, 0x0f ); | ||
659 | snd_emu1212m_fpga_read(emu, 0x11, &tmp ); | ||
660 | snd_emu1212m_fpga_write(emu, 0x11, 0x30 ); | ||
661 | snd_emu1212m_fpga_read(emu, 0x0a, &tmp ); | ||
662 | snd_emu1212m_fpga_write(emu, 0x0a, 0x10 ); | ||
663 | snd_emu1212m_fpga_write(emu, 0x0c, 0x19 ); | ||
664 | snd_emu1212m_fpga_write(emu, 0x12, 0x0c ); | ||
665 | snd_emu1212m_fpga_write(emu, 0x09, 0x0f ); | ||
666 | snd_emu1212m_fpga_write(emu, 0x06, 0x00 ); | ||
667 | snd_emu1212m_fpga_write(emu, 0x05, 0x00 ); | ||
668 | snd_emu1212m_fpga_write(emu, 0x0e, 0x12 ); | ||
669 | snd_emu1212m_fpga_netlist_write(emu, 0x0000, 0x0200); | ||
670 | snd_emu1212m_fpga_netlist_write(emu, 0x0001, 0x0201); | ||
671 | snd_emu1212m_fpga_netlist_write(emu, 0x0002, 0x0500); | ||
672 | snd_emu1212m_fpga_netlist_write(emu, 0x0003, 0x0501); | ||
673 | snd_emu1212m_fpga_netlist_write(emu, 0x0004, 0x0400); | ||
674 | snd_emu1212m_fpga_netlist_write(emu, 0x0005, 0x0401); | ||
675 | snd_emu1212m_fpga_netlist_write(emu, 0x0006, 0x0402); | ||
676 | snd_emu1212m_fpga_netlist_write(emu, 0x0007, 0x0403); | ||
677 | snd_emu1212m_fpga_netlist_write(emu, 0x0008, 0x0404); | ||
678 | snd_emu1212m_fpga_netlist_write(emu, 0x0009, 0x0405); | ||
679 | snd_emu1212m_fpga_netlist_write(emu, 0x000a, 0x0406); | ||
680 | snd_emu1212m_fpga_netlist_write(emu, 0x000b, 0x0407); | ||
681 | snd_emu1212m_fpga_netlist_write(emu, 0x000c, 0x0100); | ||
682 | snd_emu1212m_fpga_netlist_write(emu, 0x000d, 0x0104); | ||
683 | snd_emu1212m_fpga_netlist_write(emu, 0x000e, 0x0200); | ||
684 | snd_emu1212m_fpga_netlist_write(emu, 0x000f, 0x0201); | ||
685 | for (i=0;i < 0x20;i++) { | ||
686 | snd_emu1212m_fpga_netlist_write(emu, 0x0100+i, 0x0000); | ||
687 | } | 693 | } |
688 | for (i=0;i < 4;i++) { | 694 | snd_emu1010_fpga_read(emu, EMU_HANA_ID, ® ); |
689 | snd_emu1212m_fpga_netlist_write(emu, 0x0200+i, 0x0000); | 695 | snd_printdd("reg2=0x%x\n",reg); |
696 | if (reg == 0x55) { | ||
697 | /* FPGA failed to return to programming mode */ | ||
698 | return -ENODEV; | ||
690 | } | 699 | } |
691 | for (i=0;i < 7;i++) { | 700 | snd_printk(KERN_INFO "emu1010: EMU_HANA_ID=0x%x\n",reg); |
692 | snd_emu1212m_fpga_netlist_write(emu, 0x0300+i, 0x0000); | 701 | if ((err = snd_emu1010_load_firmware(emu, hana_filename)) != 0) { |
702 | snd_printk(KERN_INFO "emu1010: Loading Hana Firmware file %s failed\n", hana_filename); | ||
703 | return err; | ||
693 | } | 704 | } |
694 | for (i=0;i < 7;i++) { | 705 | |
695 | snd_emu1212m_fpga_netlist_write(emu, 0x0400+i, 0x0000); | 706 | /* ID, should read & 0x7f = 0x55 when FPGA programmed. */ |
707 | snd_emu1010_fpga_read(emu, EMU_HANA_ID, ® ); | ||
708 | if (reg != 0x55) { | ||
709 | /* FPGA failed to be programmed */ | ||
710 | snd_printk(KERN_INFO "emu1010: Loading Hana Firmware file failed, reg=0x%x\n", reg); | ||
711 | return -ENODEV; | ||
696 | } | 712 | } |
697 | snd_emu1212m_fpga_netlist_write(emu, 0x0500, 0x0108); | ||
698 | snd_emu1212m_fpga_netlist_write(emu, 0x0501, 0x010c); | ||
699 | snd_emu1212m_fpga_netlist_write(emu, 0x0600, 0x0110); | ||
700 | snd_emu1212m_fpga_netlist_write(emu, 0x0601, 0x0114); | ||
701 | snd_emu1212m_fpga_netlist_write(emu, 0x0700, 0x0118); | ||
702 | snd_emu1212m_fpga_netlist_write(emu, 0x0701, 0x011c); | ||
703 | snd_emu1212m_fpga_write(emu, 0x07, 0x01 ); | ||
704 | 713 | ||
705 | snd_emu1212m_fpga_read(emu, 0x21, &tmp ); | 714 | snd_printk(KERN_INFO "emu1010: Hana Firmware loaded\n"); |
715 | snd_emu1010_fpga_read(emu, EMU_HANA_MAJOR_REV, &tmp ); | ||
716 | snd_emu1010_fpga_read(emu, EMU_HANA_MINOR_REV, &tmp2 ); | ||
717 | snd_printk("Hana ver:%d.%d\n",tmp ,tmp2); | ||
718 | /* Enable 48Volt power to Audio Dock */ | ||
719 | snd_emu1010_fpga_write(emu, EMU_HANA_DOCK_PWR, EMU_HANA_DOCK_PWR_ON ); | ||
720 | |||
721 | snd_emu1010_fpga_read(emu, EMU_HANA_OPTION_CARDS, ® ); | ||
722 | snd_printk(KERN_INFO "emu1010: Card options=0x%x\n",reg); | ||
723 | snd_emu1010_fpga_read(emu, EMU_HANA_OPTION_CARDS, ® ); | ||
724 | snd_printk(KERN_INFO "emu1010: Card options=0x%x\n",reg); | ||
725 | snd_emu1010_fpga_read(emu, EMU_HANA_OPTICAL_TYPE, &tmp ); | ||
726 | /* ADAT input. */ | ||
727 | snd_emu1010_fpga_write(emu, EMU_HANA_OPTICAL_TYPE, 0x01 ); | ||
728 | snd_emu1010_fpga_read(emu, EMU_HANA_DOCK_PADS, &tmp ); | ||
729 | /* Set no attenuation on Audio Dock pads. */ | ||
730 | snd_emu1010_fpga_write(emu, EMU_HANA_DOCK_PADS, 0x00 ); | ||
731 | snd_emu1010_fpga_read(emu, EMU_HANA_DOCK_MISC, &tmp ); | ||
732 | /* Unmute Audio dock DACs, Headphone source DAC-4. */ | ||
733 | snd_emu1010_fpga_write(emu, EMU_HANA_DOCK_MISC, 0x30 ); | ||
734 | snd_emu1010_fpga_write(emu, EMU_HANA_DOCK_LEDS_2, 0x12 ); | ||
735 | snd_emu1010_fpga_read(emu, EMU_HANA_UNKNOWN13, &tmp ); | ||
736 | /* Unknown. */ | ||
737 | snd_emu1010_fpga_write(emu, EMU_HANA_UNKNOWN13, 0x0f ); | ||
738 | snd_emu1010_fpga_read(emu, EMU_HANA_DOCK_MISC, &tmp ); | ||
739 | snd_emu1010_fpga_write(emu, EMU_HANA_DOCK_MISC, 0x30 ); | ||
740 | snd_emu1010_fpga_read(emu, EMU_HANA_SPDIF_MODE, &tmp ); | ||
741 | /* SPDIF Format. Set Consumer mode, 24bit, copy enable */ | ||
742 | snd_emu1010_fpga_write(emu, EMU_HANA_SPDIF_MODE, 0x10 ); | ||
743 | /* MIDI routing */ | ||
744 | snd_emu1010_fpga_write(emu, EMU_HANA_MIDI, 0x19 ); | ||
745 | /* Unknown. */ | ||
746 | snd_emu1010_fpga_write(emu, EMU_HANA_UNKNOWN12, 0x0c ); | ||
747 | /* snd_emu1010_fpga_write(emu, 0x09, 0x0f ); // IRQ Enable: All on */ | ||
748 | /* IRQ Enable: All off */ | ||
749 | snd_emu1010_fpga_write(emu, EMU_HANA_IRQ_ENABLE, 0x00 ); | ||
750 | |||
751 | snd_emu1010_fpga_read(emu, EMU_HANA_OPTION_CARDS, ® ); | ||
752 | snd_printk(KERN_INFO "emu1010: Card options3=0x%x\n",reg); | ||
753 | /* Default WCLK set to 48kHz. */ | ||
754 | snd_emu1010_fpga_write(emu, EMU_HANA_DEFCLOCK, 0x00 ); | ||
755 | /* Word Clock source, Internal 48kHz x1 */ | ||
756 | snd_emu1010_fpga_write(emu, EMU_HANA_WCLOCK, EMU_HANA_WCLOCK_INT_48K ); | ||
757 | //snd_emu1010_fpga_write(emu, EMU_HANA_WCLOCK, EMU_HANA_WCLOCK_INT_48K | EMU_HANA_WCLOCK_4X ); | ||
758 | /* Audio Dock LEDs. */ | ||
759 | snd_emu1010_fpga_write(emu, EMU_HANA_DOCK_LEDS_2, 0x12 ); | ||
706 | 760 | ||
707 | outl(0x0000a000, emu->port + HCFG); | 761 | #if 0 |
762 | /* For 96kHz */ | ||
763 | snd_emu1010_fpga_link_dst_src_write(emu, | ||
764 | EMU_DST_ALICE2_EMU32_0, EMU_SRC_HAMOA_ADC_LEFT1); | ||
765 | snd_emu1010_fpga_link_dst_src_write(emu, | ||
766 | EMU_DST_ALICE2_EMU32_1, EMU_SRC_HAMOA_ADC_RIGHT1); | ||
767 | snd_emu1010_fpga_link_dst_src_write(emu, | ||
768 | EMU_DST_ALICE2_EMU32_4, EMU_SRC_HAMOA_ADC_LEFT2); | ||
769 | snd_emu1010_fpga_link_dst_src_write(emu, | ||
770 | EMU_DST_ALICE2_EMU32_5, EMU_SRC_HAMOA_ADC_RIGHT2); | ||
771 | #endif | ||
772 | #if 0 | ||
773 | /* For 192kHz */ | ||
774 | snd_emu1010_fpga_link_dst_src_write(emu, | ||
775 | EMU_DST_ALICE2_EMU32_0, EMU_SRC_HAMOA_ADC_LEFT1); | ||
776 | snd_emu1010_fpga_link_dst_src_write(emu, | ||
777 | EMU_DST_ALICE2_EMU32_1, EMU_SRC_HAMOA_ADC_RIGHT1); | ||
778 | snd_emu1010_fpga_link_dst_src_write(emu, | ||
779 | EMU_DST_ALICE2_EMU32_2, EMU_SRC_HAMOA_ADC_LEFT2); | ||
780 | snd_emu1010_fpga_link_dst_src_write(emu, | ||
781 | EMU_DST_ALICE2_EMU32_3, EMU_SRC_HAMOA_ADC_RIGHT2); | ||
782 | snd_emu1010_fpga_link_dst_src_write(emu, | ||
783 | EMU_DST_ALICE2_EMU32_4, EMU_SRC_HAMOA_ADC_LEFT3); | ||
784 | snd_emu1010_fpga_link_dst_src_write(emu, | ||
785 | EMU_DST_ALICE2_EMU32_5, EMU_SRC_HAMOA_ADC_RIGHT3); | ||
786 | snd_emu1010_fpga_link_dst_src_write(emu, | ||
787 | EMU_DST_ALICE2_EMU32_6, EMU_SRC_HAMOA_ADC_LEFT4); | ||
788 | snd_emu1010_fpga_link_dst_src_write(emu, | ||
789 | EMU_DST_ALICE2_EMU32_7, EMU_SRC_HAMOA_ADC_RIGHT4); | ||
790 | #endif | ||
791 | #if 1 | ||
792 | /* For 48kHz */ | ||
793 | snd_emu1010_fpga_link_dst_src_write(emu, | ||
794 | EMU_DST_ALICE2_EMU32_0, EMU_SRC_DOCK_MIC_A1); | ||
795 | snd_emu1010_fpga_link_dst_src_write(emu, | ||
796 | EMU_DST_ALICE2_EMU32_1, EMU_SRC_DOCK_MIC_B1); | ||
797 | snd_emu1010_fpga_link_dst_src_write(emu, | ||
798 | EMU_DST_ALICE2_EMU32_2, EMU_SRC_HAMOA_ADC_LEFT2); | ||
799 | snd_emu1010_fpga_link_dst_src_write(emu, | ||
800 | EMU_DST_ALICE2_EMU32_3, EMU_SRC_HAMOA_ADC_LEFT2); | ||
801 | snd_emu1010_fpga_link_dst_src_write(emu, | ||
802 | EMU_DST_ALICE2_EMU32_4, EMU_SRC_DOCK_ADC1_LEFT1); | ||
803 | snd_emu1010_fpga_link_dst_src_write(emu, | ||
804 | EMU_DST_ALICE2_EMU32_5, EMU_SRC_DOCK_ADC1_RIGHT1); | ||
805 | snd_emu1010_fpga_link_dst_src_write(emu, | ||
806 | EMU_DST_ALICE2_EMU32_6, EMU_SRC_DOCK_ADC2_LEFT1); | ||
807 | snd_emu1010_fpga_link_dst_src_write(emu, | ||
808 | EMU_DST_ALICE2_EMU32_7, EMU_SRC_DOCK_ADC2_RIGHT1); | ||
809 | #endif | ||
810 | #if 0 | ||
811 | /* Original */ | ||
812 | snd_emu1010_fpga_link_dst_src_write(emu, | ||
813 | EMU_DST_ALICE2_EMU32_4, EMU_SRC_HANA_ADAT); | ||
814 | snd_emu1010_fpga_link_dst_src_write(emu, | ||
815 | EMU_DST_ALICE2_EMU32_5, EMU_SRC_HANA_ADAT + 1); | ||
816 | snd_emu1010_fpga_link_dst_src_write(emu, | ||
817 | EMU_DST_ALICE2_EMU32_6, EMU_SRC_HANA_ADAT + 2); | ||
818 | snd_emu1010_fpga_link_dst_src_write(emu, | ||
819 | EMU_DST_ALICE2_EMU32_7, EMU_SRC_HANA_ADAT + 3); | ||
820 | snd_emu1010_fpga_link_dst_src_write(emu, | ||
821 | EMU_DST_ALICE2_EMU32_8, EMU_SRC_HANA_ADAT + 4); | ||
822 | snd_emu1010_fpga_link_dst_src_write(emu, | ||
823 | EMU_DST_ALICE2_EMU32_9, EMU_SRC_HANA_ADAT + 5); | ||
824 | snd_emu1010_fpga_link_dst_src_write(emu, | ||
825 | EMU_DST_ALICE2_EMU32_A, EMU_SRC_HANA_ADAT + 6); | ||
826 | snd_emu1010_fpga_link_dst_src_write(emu, | ||
827 | EMU_DST_ALICE2_EMU32_B, EMU_SRC_HANA_ADAT + 7); | ||
828 | snd_emu1010_fpga_link_dst_src_write(emu, | ||
829 | EMU_DST_ALICE2_EMU32_C, EMU_SRC_DOCK_MIC_A1); | ||
830 | snd_emu1010_fpga_link_dst_src_write(emu, | ||
831 | EMU_DST_ALICE2_EMU32_D, EMU_SRC_DOCK_MIC_B1); | ||
832 | snd_emu1010_fpga_link_dst_src_write(emu, | ||
833 | EMU_DST_ALICE2_EMU32_E, EMU_SRC_HAMOA_ADC_LEFT2); | ||
834 | snd_emu1010_fpga_link_dst_src_write(emu, | ||
835 | EMU_DST_ALICE2_EMU32_F, EMU_SRC_HAMOA_ADC_LEFT2); | ||
836 | #endif | ||
837 | for (i = 0;i < 0x20; i++ ) { | ||
838 | /* AudioDock Elink <- Silence */ | ||
839 | snd_emu1010_fpga_link_dst_src_write(emu, 0x0100+i, EMU_SRC_SILENCE); | ||
840 | } | ||
841 | for (i = 0;i < 4; i++) { | ||
842 | /* Hana SPDIF Out <- Silence */ | ||
843 | snd_emu1010_fpga_link_dst_src_write(emu, 0x0200+i, EMU_SRC_SILENCE); | ||
844 | } | ||
845 | for (i = 0;i < 7; i++) { | ||
846 | /* Hamoa DAC <- Silence */ | ||
847 | snd_emu1010_fpga_link_dst_src_write(emu, 0x0300+i, EMU_SRC_SILENCE); | ||
848 | } | ||
849 | for (i = 0;i < 7; i++) { | ||
850 | /* Hana ADAT Out <- Silence */ | ||
851 | snd_emu1010_fpga_link_dst_src_write(emu, EMU_DST_HANA_ADAT + i, EMU_SRC_SILENCE); | ||
852 | } | ||
853 | snd_emu1010_fpga_link_dst_src_write(emu, | ||
854 | EMU_DST_ALICE_I2S0_LEFT, EMU_SRC_DOCK_ADC1_LEFT1); | ||
855 | snd_emu1010_fpga_link_dst_src_write(emu, | ||
856 | EMU_DST_ALICE_I2S0_RIGHT, EMU_SRC_DOCK_ADC1_RIGHT1); | ||
857 | snd_emu1010_fpga_link_dst_src_write(emu, | ||
858 | EMU_DST_ALICE_I2S1_LEFT, EMU_SRC_DOCK_ADC2_LEFT1); | ||
859 | snd_emu1010_fpga_link_dst_src_write(emu, | ||
860 | EMU_DST_ALICE_I2S1_RIGHT, EMU_SRC_DOCK_ADC2_RIGHT1); | ||
861 | snd_emu1010_fpga_link_dst_src_write(emu, | ||
862 | EMU_DST_ALICE_I2S2_LEFT, EMU_SRC_DOCK_ADC3_LEFT1); | ||
863 | snd_emu1010_fpga_link_dst_src_write(emu, | ||
864 | EMU_DST_ALICE_I2S2_RIGHT, EMU_SRC_DOCK_ADC3_RIGHT1); | ||
865 | snd_emu1010_fpga_write(emu, EMU_HANA_UNMUTE, 0x01 ); // Unmute all | ||
866 | |||
867 | snd_emu1010_fpga_read(emu, EMU_HANA_OPTION_CARDS, &tmp ); | ||
868 | |||
869 | /* AC97 1.03, Any 32Meg of 2Gig address, Auto-Mute, EMU32 Slave, | ||
870 | * Lock Sound Memory Cache, Lock Tank Memory Cache, | ||
871 | * Mute all codecs. | ||
872 | */ | ||
873 | outl(0x0000a000, emu->port + HCFG); | ||
874 | /* AC97 1.03, Any 32Meg of 2Gig address, Auto-Mute, EMU32 Slave, | ||
875 | * Lock Sound Memory Cache, Lock Tank Memory Cache, | ||
876 | * Un-Mute all codecs. | ||
877 | */ | ||
708 | outl(0x0000a001, emu->port + HCFG); | 878 | outl(0x0000a001, emu->port + HCFG); |
879 | |||
709 | /* Initial boot complete. Now patches */ | 880 | /* Initial boot complete. Now patches */ |
710 | 881 | ||
711 | snd_emu1212m_fpga_read(emu, 0x21, &tmp ); | 882 | snd_emu1010_fpga_read(emu, EMU_HANA_OPTION_CARDS, &tmp ); |
712 | snd_emu1212m_fpga_write(emu, 0x0c, 0x19 ); | 883 | snd_emu1010_fpga_write(emu, EMU_HANA_MIDI, 0x19 ); /* MIDI Route */ |
713 | snd_emu1212m_fpga_write(emu, 0x12, 0x0c ); | 884 | snd_emu1010_fpga_write(emu, EMU_HANA_UNKNOWN12, 0x0c ); /* Unknown */ |
714 | snd_emu1212m_fpga_write(emu, 0x0c, 0x19 ); | 885 | snd_emu1010_fpga_write(emu, EMU_HANA_MIDI, 0x19 ); /* MIDI Route */ |
715 | snd_emu1212m_fpga_write(emu, 0x12, 0x0c ); | 886 | snd_emu1010_fpga_write(emu, EMU_HANA_UNKNOWN12, 0x0c ); /* Unknown */ |
716 | snd_emu1212m_fpga_read(emu, 0x0a, &tmp ); | 887 | snd_emu1010_fpga_read(emu, EMU_HANA_SPDIF_MODE, &tmp ); |
717 | snd_emu1212m_fpga_write(emu, 0x0a, 0x10 ); | 888 | snd_emu1010_fpga_write(emu, EMU_HANA_SPDIF_MODE, 0x10 ); /* SPDIF Format spdif (or 0x11 for aes/ebu) */ |
718 | 889 | ||
719 | snd_emu1212m_fpga_read(emu, 0x20, &tmp ); | 890 | /* Delay to allow Audio Dock to settle */ |
720 | snd_emu1212m_fpga_read(emu, 0x21, &tmp ); | 891 | msleep(100); |
721 | 892 | snd_emu1010_fpga_read(emu, EMU_HANA_IRQ_STATUS, &tmp ); /* IRQ Status */ | |
722 | snd_emu1212m_fpga_netlist_write(emu, 0x0300, 0x0312); | 893 | snd_emu1010_fpga_read(emu, EMU_HANA_OPTION_CARDS, ® ); /* OPTIONS: Which cards are attached to the EMU */ |
723 | snd_emu1212m_fpga_netlist_write(emu, 0x0301, 0x0313); | 894 | /* FIXME: The loading of this should be able to happen any time, |
724 | snd_emu1212m_fpga_netlist_write(emu, 0x0200, 0x0302); | 895 | * as the user can plug/unplug it at any time |
725 | snd_emu1212m_fpga_netlist_write(emu, 0x0201, 0x0303); | 896 | */ |
897 | if (reg & (EMU_HANA_OPTION_DOCK_ONLINE | EMU_HANA_OPTION_DOCK_OFFLINE) ) { | ||
898 | /* Audio Dock attached */ | ||
899 | /* Return to Audio Dock programming mode */ | ||
900 | snd_printk(KERN_INFO "emu1010: Loading Audio Dock Firmware\n"); | ||
901 | snd_emu1010_fpga_write(emu, EMU_HANA_FPGA_CONFIG, EMU_HANA_FPGA_CONFIG_AUDIODOCK ); | ||
902 | if ((err = snd_emu1010_load_firmware(emu, dock_filename)) != 0) { | ||
903 | return err; | ||
904 | } | ||
905 | snd_printk(KERN_INFO "emu1010: Audio Dock Firmware loaded\n"); | ||
906 | snd_emu1010_fpga_write(emu, EMU_HANA_FPGA_CONFIG, 0 ); | ||
907 | snd_emu1010_fpga_read(emu, EMU_HANA_IRQ_STATUS, ® ); | ||
908 | snd_printk(KERN_INFO "emu1010: EMU_HANA+DOCK_IRQ_STATUS=0x%x\n",reg); | ||
909 | /* ID, should read & 0x7f = 0x55 when FPGA programmed. */ | ||
910 | snd_emu1010_fpga_read(emu, EMU_HANA_ID, ® ); | ||
911 | snd_printk(KERN_INFO "emu1010: EMU_HANA+DOCK_ID=0x%x\n",reg); | ||
912 | if (reg != 0x55) { | ||
913 | /* FPGA failed to be programmed */ | ||
914 | snd_printk(KERN_INFO "emu1010: Loading Audio Dock Firmware file failed, reg=0x%x\n", reg); | ||
915 | return 0; | ||
916 | return -ENODEV; | ||
917 | } | ||
918 | } | ||
919 | #if 0 | ||
920 | snd_emu1010_fpga_link_dst_src_write(emu, | ||
921 | EMU_DST_HAMOA_DAC_LEFT1, EMU_SRC_ALICE_EMU32B + 2); /* ALICE2 bus 0xa2 */ | ||
922 | snd_emu1010_fpga_link_dst_src_write(emu, | ||
923 | EMU_DST_HAMOA_DAC_RIGHT1, EMU_SRC_ALICE_EMU32B + 3); /* ALICE2 bus 0xa3 */ | ||
924 | snd_emu1010_fpga_link_dst_src_write(emu, | ||
925 | EMU_DST_HANA_SPDIF_LEFT1, EMU_SRC_ALICE_EMU32A + 2); /* ALICE2 bus 0xb2 */ | ||
926 | snd_emu1010_fpga_link_dst_src_write(emu, | ||
927 | EMU_DST_HANA_SPDIF_RIGHT1, EMU_SRC_ALICE_EMU32A + 3); /* ALICE2 bus 0xb3 */ | ||
928 | #endif | ||
929 | /* Default outputs */ | ||
930 | snd_emu1010_fpga_link_dst_src_write(emu, | ||
931 | EMU_DST_DOCK_DAC1_LEFT1, EMU_SRC_ALICE_EMU32A + 0); /* ALICE2 bus 0xa0 */ | ||
932 | emu->emu1010.output_source[0] = 21; | ||
933 | snd_emu1010_fpga_link_dst_src_write(emu, | ||
934 | EMU_DST_DOCK_DAC1_RIGHT1, EMU_SRC_ALICE_EMU32A + 1); | ||
935 | emu->emu1010.output_source[1] = 22; | ||
936 | snd_emu1010_fpga_link_dst_src_write(emu, | ||
937 | EMU_DST_DOCK_DAC2_LEFT1, EMU_SRC_ALICE_EMU32A + 2); | ||
938 | emu->emu1010.output_source[2] = 23; | ||
939 | snd_emu1010_fpga_link_dst_src_write(emu, | ||
940 | EMU_DST_DOCK_DAC2_RIGHT1, EMU_SRC_ALICE_EMU32A + 3); | ||
941 | emu->emu1010.output_source[3] = 24; | ||
942 | snd_emu1010_fpga_link_dst_src_write(emu, | ||
943 | EMU_DST_DOCK_DAC3_LEFT1, EMU_SRC_ALICE_EMU32A + 4); | ||
944 | emu->emu1010.output_source[4] = 25; | ||
945 | snd_emu1010_fpga_link_dst_src_write(emu, | ||
946 | EMU_DST_DOCK_DAC3_RIGHT1, EMU_SRC_ALICE_EMU32A + 5); | ||
947 | emu->emu1010.output_source[5] = 26; | ||
948 | snd_emu1010_fpga_link_dst_src_write(emu, | ||
949 | EMU_DST_DOCK_DAC4_LEFT1, EMU_SRC_ALICE_EMU32A + 6); | ||
950 | emu->emu1010.output_source[6] = 27; | ||
951 | snd_emu1010_fpga_link_dst_src_write(emu, | ||
952 | EMU_DST_DOCK_DAC4_RIGHT1, EMU_SRC_ALICE_EMU32A + 7); | ||
953 | emu->emu1010.output_source[7] = 28; | ||
954 | snd_emu1010_fpga_link_dst_src_write(emu, | ||
955 | EMU_DST_DOCK_PHONES_LEFT1, EMU_SRC_ALICE_EMU32A + 0); /* ALICE2 bus 0xa0 */ | ||
956 | emu->emu1010.output_source[8] = 21; | ||
957 | snd_emu1010_fpga_link_dst_src_write(emu, | ||
958 | EMU_DST_DOCK_PHONES_RIGHT1, EMU_SRC_ALICE_EMU32A + 1); | ||
959 | emu->emu1010.output_source[9] = 22; | ||
960 | snd_emu1010_fpga_link_dst_src_write(emu, | ||
961 | EMU_DST_DOCK_SPDIF_LEFT1, EMU_SRC_ALICE_EMU32A + 0); /* ALICE2 bus 0xa0 */ | ||
962 | emu->emu1010.output_source[10] = 21; | ||
963 | snd_emu1010_fpga_link_dst_src_write(emu, | ||
964 | EMU_DST_DOCK_SPDIF_RIGHT1, EMU_SRC_ALICE_EMU32A + 1); | ||
965 | emu->emu1010.output_source[11] = 22; | ||
966 | snd_emu1010_fpga_link_dst_src_write(emu, | ||
967 | EMU_DST_HANA_SPDIF_LEFT1, EMU_SRC_ALICE_EMU32A + 0); /* ALICE2 bus 0xa0 */ | ||
968 | emu->emu1010.output_source[12] = 21; | ||
969 | snd_emu1010_fpga_link_dst_src_write(emu, | ||
970 | EMU_DST_HANA_SPDIF_RIGHT1, EMU_SRC_ALICE_EMU32A + 1); | ||
971 | emu->emu1010.output_source[13] = 22; | ||
972 | snd_emu1010_fpga_link_dst_src_write(emu, | ||
973 | EMU_DST_HAMOA_DAC_LEFT1, EMU_SRC_ALICE_EMU32A + 0); /* ALICE2 bus 0xa0 */ | ||
974 | emu->emu1010.output_source[14] = 21; | ||
975 | snd_emu1010_fpga_link_dst_src_write(emu, | ||
976 | EMU_DST_HAMOA_DAC_RIGHT1, EMU_SRC_ALICE_EMU32A + 1); | ||
977 | emu->emu1010.output_source[15] = 22; | ||
978 | snd_emu1010_fpga_link_dst_src_write(emu, | ||
979 | EMU_DST_HANA_ADAT, EMU_SRC_ALICE_EMU32A + 0); /* ALICE2 bus 0xa0 */ | ||
980 | emu->emu1010.output_source[16] = 21; | ||
981 | snd_emu1010_fpga_link_dst_src_write(emu, | ||
982 | EMU_DST_HANA_ADAT + 1, EMU_SRC_ALICE_EMU32A + 1); | ||
983 | emu->emu1010.output_source[17] = 22; | ||
984 | snd_emu1010_fpga_link_dst_src_write(emu, | ||
985 | EMU_DST_HANA_ADAT + 2, EMU_SRC_ALICE_EMU32A + 2); | ||
986 | emu->emu1010.output_source[18] = 23; | ||
987 | snd_emu1010_fpga_link_dst_src_write(emu, | ||
988 | EMU_DST_HANA_ADAT + 3, EMU_SRC_ALICE_EMU32A + 3); | ||
989 | emu->emu1010.output_source[19] = 24; | ||
990 | snd_emu1010_fpga_link_dst_src_write(emu, | ||
991 | EMU_DST_HANA_ADAT + 4, EMU_SRC_ALICE_EMU32A + 4); | ||
992 | emu->emu1010.output_source[20] = 25; | ||
993 | snd_emu1010_fpga_link_dst_src_write(emu, | ||
994 | EMU_DST_HANA_ADAT + 5, EMU_SRC_ALICE_EMU32A + 5); | ||
995 | emu->emu1010.output_source[21] = 26; | ||
996 | snd_emu1010_fpga_link_dst_src_write(emu, | ||
997 | EMU_DST_HANA_ADAT + 6, EMU_SRC_ALICE_EMU32A + 6); | ||
998 | emu->emu1010.output_source[22] = 27; | ||
999 | snd_emu1010_fpga_link_dst_src_write(emu, | ||
1000 | EMU_DST_HANA_ADAT + 7, EMU_SRC_ALICE_EMU32A + 7); | ||
1001 | emu->emu1010.output_source[23] = 28; | ||
1002 | |||
1003 | /* TEMP: Select SPDIF in/out */ | ||
1004 | snd_emu1010_fpga_write(emu, EMU_HANA_OPTICAL_TYPE, 0x0); /* Output spdif */ | ||
1005 | |||
1006 | /* TEMP: Select 48kHz SPDIF out */ | ||
1007 | snd_emu1010_fpga_write(emu, EMU_HANA_UNMUTE, 0x0); /* Mute all */ | ||
1008 | snd_emu1010_fpga_write(emu, EMU_HANA_DEFCLOCK, 0x0); /* Default fallback clock 48kHz */ | ||
1009 | /* Word Clock source, Internal 48kHz x1 */ | ||
1010 | snd_emu1010_fpga_write(emu, EMU_HANA_WCLOCK, EMU_HANA_WCLOCK_INT_48K ); | ||
1011 | //snd_emu1010_fpga_write(emu, EMU_HANA_WCLOCK, EMU_HANA_WCLOCK_INT_48K | EMU_HANA_WCLOCK_4X ); | ||
1012 | snd_emu1010_fpga_write(emu, EMU_HANA_DOCK_LEDS_2, 0x12);/* Set LEDs on Audio Dock */ | ||
1013 | snd_emu1010_fpga_write(emu, EMU_HANA_UNMUTE, 0x1); /* Unmute all */ | ||
1014 | //snd_emu1010_fpga_write(emu, 0x7, 0x0); /* Mute all */ | ||
1015 | //snd_emu1010_fpga_write(emu, 0x7, 0x1); /* Unmute all */ | ||
1016 | //snd_emu1010_fpga_write(emu, 0xe, 0x12); /* Set LEDs on Audio Dock */ | ||
726 | 1017 | ||
727 | return 0; | 1018 | return 0; |
728 | } | 1019 | } |
@@ -747,6 +1038,10 @@ static int snd_emu10k1_free(struct snd_emu10k1 *emu) | |||
747 | } | 1038 | } |
748 | snd_emu10k1_free_efx(emu); | 1039 | snd_emu10k1_free_efx(emu); |
749 | } | 1040 | } |
1041 | if (emu->card_capabilities->emu1010) { | ||
1042 | /* Disable 48Volt power to Audio Dock */ | ||
1043 | snd_emu1010_fpga_write(emu, EMU_HANA_DOCK_PWR, 0 ); | ||
1044 | } | ||
750 | if (emu->memhdr) | 1045 | if (emu->memhdr) |
751 | snd_util_memhdr_free(emu->memhdr); | 1046 | snd_util_memhdr_free(emu->memhdr); |
752 | if (emu->silent_page.area) | 1047 | if (emu->silent_page.area) |
@@ -865,11 +1160,12 @@ static struct snd_emu_chip_details emu_chip_details[] = { | |||
865 | .ac97_chip = 1} , | 1160 | .ac97_chip = 1} , |
866 | /* Tested by James@superbug.co.uk 8th July 2005. No sound available yet. */ | 1161 | /* Tested by James@superbug.co.uk 8th July 2005. No sound available yet. */ |
867 | {.vendor = 0x1102, .device = 0x0004, .subsystem = 0x40011102, | 1162 | {.vendor = 0x1102, .device = 0x0004, .subsystem = 0x40011102, |
868 | .driver = "Audigy2", .name = "E-mu 1212m [4001]", | 1163 | .driver = "Audigy2", .name = "E-mu 1010 [4001]", |
869 | .id = "EMU1212m", | 1164 | .id = "EMU1010", |
870 | .emu10k2_chip = 1, | 1165 | .emu10k2_chip = 1, |
871 | .ca0102_chip = 1, | 1166 | .ca0102_chip = 1, |
872 | .emu1212m = 1} , | 1167 | .spk71 = 1, |
1168 | .emu1010 = 1} , | ||
873 | /* Tested by James@superbug.co.uk 3rd July 2005 */ | 1169 | /* Tested by James@superbug.co.uk 3rd July 2005 */ |
874 | {.vendor = 0x1102, .device = 0x0004, .subsystem = 0x20071102, | 1170 | {.vendor = 0x1102, .device = 0x0004, .subsystem = 0x20071102, |
875 | .driver = "Audigy2", .name = "Audigy 4 PRO [SB0380]", | 1171 | .driver = "Audigy2", .name = "Audigy 4 PRO [SB0380]", |
@@ -1297,8 +1593,8 @@ int __devinit snd_emu10k1_create(struct snd_card *card, | |||
1297 | } else if (emu->card_capabilities->ca_cardbus_chip) { | 1593 | } else if (emu->card_capabilities->ca_cardbus_chip) { |
1298 | if ((err = snd_emu10k1_cardbus_init(emu)) < 0) | 1594 | if ((err = snd_emu10k1_cardbus_init(emu)) < 0) |
1299 | goto error; | 1595 | goto error; |
1300 | } else if (emu->card_capabilities->emu1212m) { | 1596 | } else if (emu->card_capabilities->emu1010) { |
1301 | if ((err = snd_emu10k1_emu1212m_init(emu)) < 0) { | 1597 | if ((err = snd_emu10k1_emu1010_init(emu)) < 0) { |
1302 | snd_emu10k1_free(emu); | 1598 | snd_emu10k1_free(emu); |
1303 | return err; | 1599 | return err; |
1304 | } | 1600 | } |
@@ -1446,8 +1742,8 @@ void snd_emu10k1_resume_init(struct snd_emu10k1 *emu) | |||
1446 | snd_emu10k1_ecard_init(emu); | 1742 | snd_emu10k1_ecard_init(emu); |
1447 | else if (emu->card_capabilities->ca_cardbus_chip) | 1743 | else if (emu->card_capabilities->ca_cardbus_chip) |
1448 | snd_emu10k1_cardbus_init(emu); | 1744 | snd_emu10k1_cardbus_init(emu); |
1449 | else if (emu->card_capabilities->emu1212m) | 1745 | else if (emu->card_capabilities->emu1010) |
1450 | snd_emu10k1_emu1212m_init(emu); | 1746 | snd_emu10k1_emu1010_init(emu); |
1451 | else | 1747 | else |
1452 | snd_emu10k1_ptr_write(emu, AC97SLOT, 0, AC97SLOT_CNTR|AC97SLOT_LFE); | 1748 | snd_emu10k1_ptr_write(emu, AC97SLOT, 0, AC97SLOT_CNTR|AC97SLOT_LFE); |
1453 | snd_emu10k1_init(emu, emu->enable_ir, 1); | 1749 | snd_emu10k1_init(emu, emu->enable_ir, 1); |
diff --git a/sound/pci/emu10k1/emu10k1x.c b/sound/pci/emu10k1/emu10k1x.c index 2199b42a6019..bb0fec7f7e1b 100644 --- a/sound/pci/emu10k1/emu10k1x.c +++ b/sound/pci/emu10k1/emu10k1x.c | |||
@@ -460,7 +460,7 @@ static int snd_emu10k1x_pcm_prepare(struct snd_pcm_substream *substream) | |||
460 | u32 period_size_bytes = frames_to_bytes(runtime, runtime->period_size); | 460 | u32 period_size_bytes = frames_to_bytes(runtime, runtime->period_size); |
461 | int i; | 461 | int i; |
462 | 462 | ||
463 | for(i=0; i < runtime->periods; i++) { | 463 | for(i = 0; i < runtime->periods; i++) { |
464 | *table_base++=runtime->dma_addr+(i*period_size_bytes); | 464 | *table_base++=runtime->dma_addr+(i*period_size_bytes); |
465 | *table_base++=period_size_bytes<<16; | 465 | *table_base++=period_size_bytes<<16; |
466 | } | 466 | } |
@@ -1042,8 +1042,8 @@ static void snd_emu10k1x_proc_reg_write(struct snd_info_entry *entry, | |||
1042 | if (sscanf(line, "%x %x %x", ®, &channel_id, &val) != 3) | 1042 | if (sscanf(line, "%x %x %x", ®, &channel_id, &val) != 3) |
1043 | continue; | 1043 | continue; |
1044 | 1044 | ||
1045 | if ((reg < 0x49) && (reg >=0) && (val <= 0xffffffff) | 1045 | if ((reg < 0x49) && (reg >= 0) && (val <= 0xffffffff) |
1046 | && (channel_id >=0) && (channel_id <= 2) ) | 1046 | && (channel_id >= 0) && (channel_id <= 2) ) |
1047 | snd_emu10k1x_ptr_write(emu, reg, channel_id, val); | 1047 | snd_emu10k1x_ptr_write(emu, reg, channel_id, val); |
1048 | } | 1048 | } |
1049 | } | 1049 | } |
diff --git a/sound/pci/emu10k1/emufx.c b/sound/pci/emu10k1/emufx.c index 13cd6ce89811..d8e8db89535f 100644 --- a/sound/pci/emu10k1/emufx.c +++ b/sound/pci/emu10k1/emufx.c | |||
@@ -3,6 +3,9 @@ | |||
3 | * Creative Labs, Inc. | 3 | * Creative Labs, Inc. |
4 | * Routines for effect processor FX8010 | 4 | * Routines for effect processor FX8010 |
5 | * | 5 | * |
6 | * Copyright (c) by James Courtier-Dutton <James@superbug.co.uk> | ||
7 | * Added EMU 1010 support. | ||
8 | * | ||
6 | * BUGS: | 9 | * BUGS: |
7 | * -- | 10 | * -- |
8 | * | 11 | * |
@@ -1069,6 +1072,21 @@ snd_emu10k1_init_stereo_onoff_control(struct snd_emu10k1_fx8010_control_gpr *ctl | |||
1069 | ctl->translation = EMU10K1_GPR_TRANSLATION_ONOFF; | 1072 | ctl->translation = EMU10K1_GPR_TRANSLATION_ONOFF; |
1070 | } | 1073 | } |
1071 | 1074 | ||
1075 | static int snd_emu10k1_audigy_dsp_convert_32_to_2x16( | ||
1076 | struct snd_emu10k1_fx8010_code *icode, | ||
1077 | u32 *ptr, int tmp, int bit_shifter16, | ||
1078 | int reg_in, int reg_out) | ||
1079 | { | ||
1080 | A_OP(icode, ptr, iACC3, A_GPR(tmp + 1), reg_in, A_C_00000000, A_C_00000000); | ||
1081 | A_OP(icode, ptr, iANDXOR, A_GPR(tmp), A_GPR(tmp + 1), A_GPR(bit_shifter16 - 1), A_C_00000000); | ||
1082 | A_OP(icode, ptr, iTSTNEG, A_GPR(tmp + 2), A_GPR(tmp), A_C_80000000, A_GPR(bit_shifter16 - 2)); | ||
1083 | A_OP(icode, ptr, iANDXOR, A_GPR(tmp + 2), A_GPR(tmp + 2), A_C_80000000, A_C_00000000); | ||
1084 | A_OP(icode, ptr, iANDXOR, A_GPR(tmp), A_GPR(tmp), A_GPR(bit_shifter16 - 3), A_C_00000000); | ||
1085 | A_OP(icode, ptr, iMACINT0, A_GPR(tmp), A_C_00000000, A_GPR(tmp), A_C_00010000); | ||
1086 | A_OP(icode, ptr, iANDXOR, reg_out, A_GPR(tmp), A_C_ffffffff, A_GPR(tmp + 2)); | ||
1087 | A_OP(icode, ptr, iACC3, reg_out + 1, A_GPR(tmp + 1), A_C_00000000, A_C_00000000); | ||
1088 | return 1; | ||
1089 | } | ||
1072 | 1090 | ||
1073 | /* | 1091 | /* |
1074 | * initial DSP configuration for Audigy | 1092 | * initial DSP configuration for Audigy |
@@ -1077,6 +1095,7 @@ snd_emu10k1_init_stereo_onoff_control(struct snd_emu10k1_fx8010_control_gpr *ctl | |||
1077 | static int __devinit _snd_emu10k1_audigy_init_efx(struct snd_emu10k1 *emu) | 1095 | static int __devinit _snd_emu10k1_audigy_init_efx(struct snd_emu10k1 *emu) |
1078 | { | 1096 | { |
1079 | int err, i, z, gpr, nctl; | 1097 | int err, i, z, gpr, nctl; |
1098 | int bit_shifter16; | ||
1080 | const int playback = 10; | 1099 | const int playback = 10; |
1081 | const int capture = playback + (SND_EMU10K1_PLAYBACK_CHANNELS * 2); /* we reserve 10 voices */ | 1100 | const int capture = playback + (SND_EMU10K1_PLAYBACK_CHANNELS * 2); /* we reserve 10 voices */ |
1082 | const int stereo_mix = capture + 2; | 1101 | const int stereo_mix = capture + 2; |
@@ -1114,17 +1133,14 @@ static int __devinit _snd_emu10k1_audigy_init_efx(struct snd_emu10k1 *emu) | |||
1114 | ptr = 0; | 1133 | ptr = 0; |
1115 | nctl = 0; | 1134 | nctl = 0; |
1116 | gpr = stereo_mix + 10; | 1135 | gpr = stereo_mix + 10; |
1136 | gpr_map[gpr++] = 0x00007fff; | ||
1137 | gpr_map[gpr++] = 0x00008000; | ||
1138 | gpr_map[gpr++] = 0x0000ffff; | ||
1139 | bit_shifter16 = gpr; | ||
1117 | 1140 | ||
1118 | /* stop FX processor */ | 1141 | /* stop FX processor */ |
1119 | snd_emu10k1_ptr_write(emu, A_DBG, 0, (emu->fx8010.dbg = 0) | A_DBG_SINGLE_STEP); | 1142 | snd_emu10k1_ptr_write(emu, A_DBG, 0, (emu->fx8010.dbg = 0) | A_DBG_SINGLE_STEP); |
1120 | 1143 | ||
1121 | #if 0 | ||
1122 | /* FIX: jcd test */ | ||
1123 | for (z = 0; z < 80; z=z+2) { | ||
1124 | A_OP(icode, &ptr, iACC3, A_EXTOUT(z), A_FXBUS(FXBUS_PCM_LEFT_FRONT), A_C_00000000, A_C_00000000); /* left */ | ||
1125 | A_OP(icode, &ptr, iACC3, A_EXTOUT(z+1), A_FXBUS(FXBUS_PCM_RIGHT_FRONT), A_C_00000000, A_C_00000000); /* right */ | ||
1126 | } | ||
1127 | #endif /* jcd test */ | ||
1128 | #if 1 | 1144 | #if 1 |
1129 | /* PCM front Playback Volume (independent from stereo mix) */ | 1145 | /* PCM front Playback Volume (independent from stereo mix) */ |
1130 | A_OP(icode, &ptr, iMAC0, A_GPR(playback), A_C_00000000, A_GPR(gpr), A_FXBUS(FXBUS_PCM_LEFT_FRONT)); | 1146 | A_OP(icode, &ptr, iMAC0, A_GPR(playback), A_C_00000000, A_GPR(gpr), A_FXBUS(FXBUS_PCM_LEFT_FRONT)); |
@@ -1182,13 +1198,20 @@ static int __devinit _snd_emu10k1_audigy_init_efx(struct snd_emu10k1 *emu) | |||
1182 | A_OP(icode, &ptr, iMAC0, A_GPR(capture+1), A_GPR(capture+1), A_GPR(gpr+1), A_FXBUS(FXBUS_MIDI_RIGHT)); | 1198 | A_OP(icode, &ptr, iMAC0, A_GPR(capture+1), A_GPR(capture+1), A_GPR(gpr+1), A_FXBUS(FXBUS_MIDI_RIGHT)); |
1183 | snd_emu10k1_init_stereo_control(&controls[nctl++], "Synth Capture Volume", gpr, 0); | 1199 | snd_emu10k1_init_stereo_control(&controls[nctl++], "Synth Capture Volume", gpr, 0); |
1184 | gpr += 2; | 1200 | gpr += 2; |
1185 | 1201 | ||
1186 | /* | 1202 | /* |
1187 | * inputs | 1203 | * inputs |
1188 | */ | 1204 | */ |
1189 | #define A_ADD_VOLUME_IN(var,vol,input) \ | 1205 | #define A_ADD_VOLUME_IN(var,vol,input) \ |
1190 | A_OP(icode, &ptr, iMAC0, A_GPR(var), A_GPR(var), A_GPR(vol), A_EXTIN(input)) | 1206 | A_OP(icode, &ptr, iMAC0, A_GPR(var), A_GPR(var), A_GPR(vol), A_EXTIN(input)) |
1191 | 1207 | ||
1208 | /* emu1212 DSP 0 and DSP 1 Capture */ | ||
1209 | if (emu->card_capabilities->emu1010) { | ||
1210 | A_OP(icode, &ptr, iMAC0, A_GPR(capture+0), A_GPR(capture+0), A_GPR(gpr), A_P16VIN(0x0)); | ||
1211 | A_OP(icode, &ptr, iMAC0, A_GPR(capture+1), A_GPR(capture+1), A_GPR(gpr+1), A_P16VIN(0x1)); | ||
1212 | snd_emu10k1_init_stereo_control(&controls[nctl++], "EMU Capture Volume", gpr, 0); | ||
1213 | gpr += 2; | ||
1214 | } | ||
1192 | /* AC'97 Playback Volume - used only for mic (renamed later) */ | 1215 | /* AC'97 Playback Volume - used only for mic (renamed later) */ |
1193 | A_ADD_VOLUME_IN(stereo_mix, gpr, A_EXTIN_AC97_L); | 1216 | A_ADD_VOLUME_IN(stereo_mix, gpr, A_EXTIN_AC97_L); |
1194 | A_ADD_VOLUME_IN(stereo_mix+1, gpr+1, A_EXTIN_AC97_R); | 1217 | A_ADD_VOLUME_IN(stereo_mix+1, gpr+1, A_EXTIN_AC97_R); |
@@ -1429,6 +1452,13 @@ A_OP(icode, &ptr, iMAC0, A_GPR(var), A_GPR(var), A_GPR(vol), A_EXTIN(input)) | |||
1429 | 1452 | ||
1430 | /* digital outputs */ | 1453 | /* digital outputs */ |
1431 | /* A_PUT_STEREO_OUTPUT(A_EXTOUT_FRONT_L, A_EXTOUT_FRONT_R, playback + SND_EMU10K1_PLAYBACK_CHANNELS); */ | 1454 | /* A_PUT_STEREO_OUTPUT(A_EXTOUT_FRONT_L, A_EXTOUT_FRONT_R, playback + SND_EMU10K1_PLAYBACK_CHANNELS); */ |
1455 | if (emu->card_capabilities->emu1010) { | ||
1456 | /* EMU1010 Outputs from PCM Front, Rear, Center, LFE, Side */ | ||
1457 | snd_printk("EMU outputs on\n"); | ||
1458 | for (z = 0; z < 8; z++) { | ||
1459 | A_OP(icode, &ptr, iACC3, A_EMU32OUTL(z), A_GPR(playback + SND_EMU10K1_PLAYBACK_CHANNELS + z), A_C_00000000, A_C_00000000); | ||
1460 | } | ||
1461 | } | ||
1432 | 1462 | ||
1433 | /* IEC958 Optical Raw Playback Switch */ | 1463 | /* IEC958 Optical Raw Playback Switch */ |
1434 | gpr_map[gpr++] = 0; | 1464 | gpr_map[gpr++] = 0; |
@@ -1466,9 +1496,57 @@ A_OP(icode, &ptr, iMAC0, A_GPR(var), A_GPR(var), A_GPR(vol), A_EXTIN(input)) | |||
1466 | A_PUT_OUTPUT(A_EXTOUT_ADC_CAP_R, capture+1); | 1496 | A_PUT_OUTPUT(A_EXTOUT_ADC_CAP_R, capture+1); |
1467 | #endif | 1497 | #endif |
1468 | 1498 | ||
1469 | /* EFX capture - capture the 16 EXTINs */ | 1499 | if (emu->card_capabilities->emu1010) { |
1470 | for (z = 0; z < 16; z++) { | 1500 | snd_printk("EMU inputs on\n"); |
1471 | A_OP(icode, &ptr, iACC3, A_FXBUS2(z), A_C_00000000, A_C_00000000, A_EXTIN(z)); | 1501 | /* Capture 8 channels of S32_LE sound */ |
1502 | |||
1503 | /* printk("emufx.c: gpr=0x%x, tmp=0x%x\n",gpr, tmp); */ | ||
1504 | /* For the EMU1010: How to get 32bit values from the DSP. High 16bits into L, low 16bits into R. */ | ||
1505 | /* A_P16VIN(0) is delayed by one sample, | ||
1506 | * so all other A_P16VIN channels will need to also be delayed | ||
1507 | */ | ||
1508 | /* Left ADC in. 1 of 2 */ | ||
1509 | snd_emu10k1_audigy_dsp_convert_32_to_2x16( icode, &ptr, tmp, bit_shifter16, A_P16VIN(0x0), A_FXBUS2(0) ); | ||
1510 | /* Right ADC in 1 of 2 */ | ||
1511 | gpr_map[gpr++] = 0x00000000; | ||
1512 | snd_emu10k1_audigy_dsp_convert_32_to_2x16( icode, &ptr, tmp, bit_shifter16, A_GPR(gpr - 1), A_FXBUS2(2) ); | ||
1513 | A_OP(icode, &ptr, iACC3, A_GPR(gpr - 1), A_P16VIN(0x1), A_C_00000000, A_C_00000000); | ||
1514 | gpr_map[gpr++] = 0x00000000; | ||
1515 | snd_emu10k1_audigy_dsp_convert_32_to_2x16( icode, &ptr, tmp, bit_shifter16, A_GPR(gpr - 1), A_FXBUS2(4) ); | ||
1516 | A_OP(icode, &ptr, iACC3, A_GPR(gpr - 1), A_P16VIN(0x2), A_C_00000000, A_C_00000000); | ||
1517 | gpr_map[gpr++] = 0x00000000; | ||
1518 | snd_emu10k1_audigy_dsp_convert_32_to_2x16( icode, &ptr, tmp, bit_shifter16, A_GPR(gpr - 1), A_FXBUS2(6) ); | ||
1519 | A_OP(icode, &ptr, iACC3, A_GPR(gpr - 1), A_P16VIN(0x3), A_C_00000000, A_C_00000000); | ||
1520 | /* For 96kHz mode */ | ||
1521 | /* Left ADC in. 2 of 2 */ | ||
1522 | gpr_map[gpr++] = 0x00000000; | ||
1523 | snd_emu10k1_audigy_dsp_convert_32_to_2x16( icode, &ptr, tmp, bit_shifter16, A_GPR(gpr - 1), A_FXBUS2(0x8) ); | ||
1524 | A_OP(icode, &ptr, iACC3, A_GPR(gpr - 1), A_P16VIN(0x4), A_C_00000000, A_C_00000000); | ||
1525 | /* Right ADC in 2 of 2 */ | ||
1526 | gpr_map[gpr++] = 0x00000000; | ||
1527 | snd_emu10k1_audigy_dsp_convert_32_to_2x16( icode, &ptr, tmp, bit_shifter16, A_GPR(gpr - 1), A_FXBUS2(0xa) ); | ||
1528 | A_OP(icode, &ptr, iACC3, A_GPR(gpr - 1), A_P16VIN(0x5), A_C_00000000, A_C_00000000); | ||
1529 | gpr_map[gpr++] = 0x00000000; | ||
1530 | snd_emu10k1_audigy_dsp_convert_32_to_2x16( icode, &ptr, tmp, bit_shifter16, A_GPR(gpr - 1), A_FXBUS2(0xc) ); | ||
1531 | A_OP(icode, &ptr, iACC3, A_GPR(gpr - 1), A_P16VIN(0x6), A_C_00000000, A_C_00000000); | ||
1532 | gpr_map[gpr++] = 0x00000000; | ||
1533 | snd_emu10k1_audigy_dsp_convert_32_to_2x16( icode, &ptr, tmp, bit_shifter16, A_GPR(gpr - 1), A_FXBUS2(0xe) ); | ||
1534 | A_OP(icode, &ptr, iACC3, A_GPR(gpr - 1), A_P16VIN(0x7), A_C_00000000, A_C_00000000); | ||
1535 | |||
1536 | #if 0 | ||
1537 | for (z = 4; z < 8; z++) { | ||
1538 | A_OP(icode, &ptr, iACC3, A_FXBUS2(z), A_C_00000000, A_C_00000000, A_C_00000000); | ||
1539 | } | ||
1540 | for (z = 0xc; z < 0x10; z++) { | ||
1541 | A_OP(icode, &ptr, iACC3, A_FXBUS2(z), A_C_00000000, A_C_00000000, A_C_00000000); | ||
1542 | } | ||
1543 | #endif | ||
1544 | } else { | ||
1545 | /* EFX capture - capture the 16 EXTINs */ | ||
1546 | /* Capture 16 channels of S16_LE sound */ | ||
1547 | for (z = 0; z < 16; z++) { | ||
1548 | A_OP(icode, &ptr, iACC3, A_FXBUS2(z), A_C_00000000, A_C_00000000, A_EXTIN(z)); | ||
1549 | } | ||
1472 | } | 1550 | } |
1473 | 1551 | ||
1474 | #endif /* JCD test */ | 1552 | #endif /* JCD test */ |
@@ -2138,7 +2216,7 @@ void snd_emu10k1_free_efx(struct snd_emu10k1 *emu) | |||
2138 | snd_emu10k1_ptr_write(emu, DBG, 0, emu->fx8010.dbg = EMU10K1_DBG_SINGLE_STEP); | 2216 | snd_emu10k1_ptr_write(emu, DBG, 0, emu->fx8010.dbg = EMU10K1_DBG_SINGLE_STEP); |
2139 | } | 2217 | } |
2140 | 2218 | ||
2141 | #if 0 // FIXME: who use them? | 2219 | #if 0 /* FIXME: who use them? */ |
2142 | int snd_emu10k1_fx8010_tone_control_activate(struct snd_emu10k1 *emu, int output) | 2220 | int snd_emu10k1_fx8010_tone_control_activate(struct snd_emu10k1 *emu, int output) |
2143 | { | 2221 | { |
2144 | if (output < 0 || output >= 6) | 2222 | if (output < 0 || output >= 6) |
diff --git a/sound/pci/emu10k1/emumixer.c b/sound/pci/emu10k1/emumixer.c index c31f3d0877fa..c8176dc8142f 100644 --- a/sound/pci/emu10k1/emumixer.c +++ b/sound/pci/emu10k1/emumixer.c | |||
@@ -5,6 +5,9 @@ | |||
5 | * Routines for control of EMU10K1 chips / mixer routines | 5 | * Routines for control of EMU10K1 chips / mixer routines |
6 | * Multichannel PCM support Copyright (c) Lee Revell <rlrevell@joe-job.com> | 6 | * Multichannel PCM support Copyright (c) Lee Revell <rlrevell@joe-job.com> |
7 | * | 7 | * |
8 | * Copyright (c) by James Courtier-Dutton <James@superbug.co.uk> | ||
9 | * Added EMU 1010 support. | ||
10 | * | ||
8 | * BUGS: | 11 | * BUGS: |
9 | * -- | 12 | * -- |
10 | * | 13 | * |
@@ -68,6 +71,311 @@ static int snd_emu10k1_spdif_get_mask(struct snd_kcontrol *kcontrol, | |||
68 | return 0; | 71 | return 0; |
69 | } | 72 | } |
70 | 73 | ||
74 | static char *emu1010_src_texts[] = { | ||
75 | "Silence", | ||
76 | "Dock Mic A", | ||
77 | "Dock Mic B", | ||
78 | "Dock ADC1 Left", | ||
79 | "Dock ADC1 Right", | ||
80 | "Dock ADC2 Left", | ||
81 | "Dock ADC2 Right", | ||
82 | "Dock ADC3 Left", | ||
83 | "Dock ADC3 Right", | ||
84 | "0202 ADC Left", | ||
85 | "0202 ADC Right", | ||
86 | "0202 SPDIF Left", | ||
87 | "0202 SPDIF Right", | ||
88 | "ADAT 0", | ||
89 | "ADAT 1", | ||
90 | "ADAT 2", | ||
91 | "ADAT 3", | ||
92 | "ADAT 4", | ||
93 | "ADAT 5", | ||
94 | "ADAT 6", | ||
95 | "ADAT 7", | ||
96 | "DSP 0", | ||
97 | "DSP 1", | ||
98 | "DSP 2", | ||
99 | "DSP 3", | ||
100 | "DSP 4", | ||
101 | "DSP 5", | ||
102 | "DSP 6", | ||
103 | "DSP 7", | ||
104 | "DSP 8", | ||
105 | "DSP 9", | ||
106 | "DSP 10", | ||
107 | "DSP 11", | ||
108 | "DSP 12", | ||
109 | "DSP 13", | ||
110 | "DSP 14", | ||
111 | "DSP 15", | ||
112 | "DSP 16", | ||
113 | "DSP 17", | ||
114 | "DSP 18", | ||
115 | "DSP 19", | ||
116 | "DSP 20", | ||
117 | "DSP 21", | ||
118 | "DSP 22", | ||
119 | "DSP 23", | ||
120 | "DSP 24", | ||
121 | "DSP 25", | ||
122 | "DSP 26", | ||
123 | "DSP 27", | ||
124 | "DSP 28", | ||
125 | "DSP 29", | ||
126 | "DSP 30", | ||
127 | "DSP 31", | ||
128 | }; | ||
129 | |||
130 | static unsigned int emu1010_src_regs[] = { | ||
131 | EMU_SRC_SILENCE,/* 0 */ | ||
132 | EMU_SRC_DOCK_MIC_A1, /* 1 */ | ||
133 | EMU_SRC_DOCK_MIC_B1, /* 2 */ | ||
134 | EMU_SRC_DOCK_ADC1_LEFT1, /* 3 */ | ||
135 | EMU_SRC_DOCK_ADC1_RIGHT1, /* 4 */ | ||
136 | EMU_SRC_DOCK_ADC2_LEFT1, /* 5 */ | ||
137 | EMU_SRC_DOCK_ADC2_RIGHT1, /* 6 */ | ||
138 | EMU_SRC_DOCK_ADC3_LEFT1, /* 7 */ | ||
139 | EMU_SRC_DOCK_ADC3_RIGHT1, /* 8 */ | ||
140 | EMU_SRC_HAMOA_ADC_LEFT1, /* 9 */ | ||
141 | EMU_SRC_HAMOA_ADC_RIGHT1, /* 10 */ | ||
142 | EMU_SRC_HANA_SPDIF_LEFT1, /* 11 */ | ||
143 | EMU_SRC_HANA_SPDIF_RIGHT1, /* 12 */ | ||
144 | EMU_SRC_HANA_ADAT, /* 13 */ | ||
145 | EMU_SRC_HANA_ADAT+1, /* 14 */ | ||
146 | EMU_SRC_HANA_ADAT+2, /* 15 */ | ||
147 | EMU_SRC_HANA_ADAT+3, /* 16 */ | ||
148 | EMU_SRC_HANA_ADAT+4, /* 17 */ | ||
149 | EMU_SRC_HANA_ADAT+5, /* 18 */ | ||
150 | EMU_SRC_HANA_ADAT+6, /* 19 */ | ||
151 | EMU_SRC_HANA_ADAT+7, /* 20 */ | ||
152 | EMU_SRC_ALICE_EMU32A, /* 21 */ | ||
153 | EMU_SRC_ALICE_EMU32A+1, /* 22 */ | ||
154 | EMU_SRC_ALICE_EMU32A+2, /* 23 */ | ||
155 | EMU_SRC_ALICE_EMU32A+3, /* 24 */ | ||
156 | EMU_SRC_ALICE_EMU32A+4, /* 25 */ | ||
157 | EMU_SRC_ALICE_EMU32A+5, /* 26 */ | ||
158 | EMU_SRC_ALICE_EMU32A+6, /* 27 */ | ||
159 | EMU_SRC_ALICE_EMU32A+7, /* 28 */ | ||
160 | EMU_SRC_ALICE_EMU32A+8, /* 29 */ | ||
161 | EMU_SRC_ALICE_EMU32A+9, /* 30 */ | ||
162 | EMU_SRC_ALICE_EMU32A+0xa, /* 31 */ | ||
163 | EMU_SRC_ALICE_EMU32A+0xb, /* 32 */ | ||
164 | EMU_SRC_ALICE_EMU32A+0xc, /* 33 */ | ||
165 | EMU_SRC_ALICE_EMU32A+0xd, /* 34 */ | ||
166 | EMU_SRC_ALICE_EMU32A+0xe, /* 35 */ | ||
167 | EMU_SRC_ALICE_EMU32A+0xf, /* 36 */ | ||
168 | EMU_SRC_ALICE_EMU32B, /* 37 */ | ||
169 | EMU_SRC_ALICE_EMU32B+1, /* 38 */ | ||
170 | EMU_SRC_ALICE_EMU32B+2, /* 39 */ | ||
171 | EMU_SRC_ALICE_EMU32B+3, /* 40 */ | ||
172 | EMU_SRC_ALICE_EMU32B+4, /* 41 */ | ||
173 | EMU_SRC_ALICE_EMU32B+5, /* 42 */ | ||
174 | EMU_SRC_ALICE_EMU32B+6, /* 43 */ | ||
175 | EMU_SRC_ALICE_EMU32B+7, /* 44 */ | ||
176 | EMU_SRC_ALICE_EMU32B+8, /* 45 */ | ||
177 | EMU_SRC_ALICE_EMU32B+9, /* 46 */ | ||
178 | EMU_SRC_ALICE_EMU32B+0xa, /* 47 */ | ||
179 | EMU_SRC_ALICE_EMU32B+0xb, /* 48 */ | ||
180 | EMU_SRC_ALICE_EMU32B+0xc, /* 49 */ | ||
181 | EMU_SRC_ALICE_EMU32B+0xd, /* 50 */ | ||
182 | EMU_SRC_ALICE_EMU32B+0xe, /* 51 */ | ||
183 | EMU_SRC_ALICE_EMU32B+0xf, /* 52 */ | ||
184 | }; | ||
185 | |||
186 | static unsigned int emu1010_output_dst[] = { | ||
187 | EMU_DST_DOCK_DAC1_LEFT1, /* 0 */ | ||
188 | EMU_DST_DOCK_DAC1_RIGHT1, /* 1 */ | ||
189 | EMU_DST_DOCK_DAC2_LEFT1, /* 2 */ | ||
190 | EMU_DST_DOCK_DAC2_RIGHT1, /* 3 */ | ||
191 | EMU_DST_DOCK_DAC3_LEFT1, /* 4 */ | ||
192 | EMU_DST_DOCK_DAC3_RIGHT1, /* 5 */ | ||
193 | EMU_DST_DOCK_DAC4_LEFT1, /* 6 */ | ||
194 | EMU_DST_DOCK_DAC4_RIGHT1, /* 7 */ | ||
195 | EMU_DST_DOCK_PHONES_LEFT1, /* 8 */ | ||
196 | EMU_DST_DOCK_PHONES_RIGHT1, /* 9 */ | ||
197 | EMU_DST_DOCK_SPDIF_LEFT1, /* 10 */ | ||
198 | EMU_DST_DOCK_SPDIF_RIGHT1, /* 11 */ | ||
199 | EMU_DST_HANA_SPDIF_LEFT1, /* 12 */ | ||
200 | EMU_DST_HANA_SPDIF_RIGHT1, /* 13 */ | ||
201 | EMU_DST_HAMOA_DAC_LEFT1, /* 14 */ | ||
202 | EMU_DST_HAMOA_DAC_RIGHT1, /* 15 */ | ||
203 | EMU_DST_HANA_ADAT, /* 16 */ | ||
204 | EMU_DST_HANA_ADAT+1, /* 17 */ | ||
205 | EMU_DST_HANA_ADAT+2, /* 18 */ | ||
206 | EMU_DST_HANA_ADAT+3, /* 19 */ | ||
207 | EMU_DST_HANA_ADAT+4, /* 20 */ | ||
208 | EMU_DST_HANA_ADAT+5, /* 21 */ | ||
209 | EMU_DST_HANA_ADAT+6, /* 22 */ | ||
210 | EMU_DST_HANA_ADAT+7, /* 23 */ | ||
211 | }; | ||
212 | |||
213 | static unsigned int emu1010_input_dst[] = { | ||
214 | EMU_DST_ALICE2_EMU32_0, | ||
215 | EMU_DST_ALICE2_EMU32_1, | ||
216 | EMU_DST_ALICE2_EMU32_2, | ||
217 | EMU_DST_ALICE2_EMU32_3, | ||
218 | EMU_DST_ALICE2_EMU32_4, | ||
219 | EMU_DST_ALICE2_EMU32_5, | ||
220 | EMU_DST_ALICE2_EMU32_6, | ||
221 | EMU_DST_ALICE2_EMU32_7, | ||
222 | EMU_DST_ALICE2_EMU32_8, | ||
223 | EMU_DST_ALICE2_EMU32_9, | ||
224 | EMU_DST_ALICE2_EMU32_A, | ||
225 | EMU_DST_ALICE2_EMU32_B, | ||
226 | EMU_DST_ALICE2_EMU32_C, | ||
227 | EMU_DST_ALICE2_EMU32_D, | ||
228 | EMU_DST_ALICE2_EMU32_E, | ||
229 | EMU_DST_ALICE2_EMU32_F, | ||
230 | EMU_DST_ALICE_I2S0_LEFT, | ||
231 | EMU_DST_ALICE_I2S0_RIGHT, | ||
232 | EMU_DST_ALICE_I2S1_LEFT, | ||
233 | EMU_DST_ALICE_I2S1_RIGHT, | ||
234 | EMU_DST_ALICE_I2S2_LEFT, | ||
235 | EMU_DST_ALICE_I2S2_RIGHT, | ||
236 | }; | ||
237 | |||
238 | static int snd_emu1010_input_output_source_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo) | ||
239 | { | ||
240 | uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED; | ||
241 | uinfo->count = 1; | ||
242 | uinfo->value.enumerated.items = 53; | ||
243 | if (uinfo->value.enumerated.item >= uinfo->value.enumerated.items) | ||
244 | uinfo->value.enumerated.item = uinfo->value.enumerated.items - 1; | ||
245 | strcpy(uinfo->value.enumerated.name, emu1010_src_texts[uinfo->value.enumerated.item]); | ||
246 | return 0; | ||
247 | } | ||
248 | |||
249 | static int snd_emu1010_output_source_get(struct snd_kcontrol *kcontrol, | ||
250 | struct snd_ctl_elem_value *ucontrol) | ||
251 | { | ||
252 | struct snd_emu10k1 *emu = snd_kcontrol_chip(kcontrol); | ||
253 | int channel; | ||
254 | |||
255 | channel = (kcontrol->private_value) & 0xff; | ||
256 | ucontrol->value.enumerated.item[0] = emu->emu1010.output_source[channel]; | ||
257 | return 0; | ||
258 | } | ||
259 | |||
260 | static int snd_emu1010_output_source_put(struct snd_kcontrol *kcontrol, | ||
261 | struct snd_ctl_elem_value *ucontrol) | ||
262 | { | ||
263 | struct snd_emu10k1 *emu = snd_kcontrol_chip(kcontrol); | ||
264 | int change = 0; | ||
265 | unsigned int val; | ||
266 | int channel; | ||
267 | |||
268 | channel = (kcontrol->private_value) & 0xff; | ||
269 | if (emu->emu1010.output_source[channel] != ucontrol->value.enumerated.item[0]) { | ||
270 | val = emu->emu1010.output_source[channel] = ucontrol->value.enumerated.item[0]; | ||
271 | change = 1; | ||
272 | snd_emu1010_fpga_link_dst_src_write(emu, | ||
273 | emu1010_output_dst[channel], emu1010_src_regs[val]); | ||
274 | } | ||
275 | return change; | ||
276 | } | ||
277 | |||
278 | static int snd_emu1010_input_source_get(struct snd_kcontrol *kcontrol, | ||
279 | struct snd_ctl_elem_value *ucontrol) | ||
280 | { | ||
281 | struct snd_emu10k1 *emu = snd_kcontrol_chip(kcontrol); | ||
282 | int channel; | ||
283 | |||
284 | channel = (kcontrol->private_value) & 0xff; | ||
285 | ucontrol->value.enumerated.item[0] = emu->emu1010.input_source[channel]; | ||
286 | return 0; | ||
287 | } | ||
288 | |||
289 | static int snd_emu1010_input_source_put(struct snd_kcontrol *kcontrol, | ||
290 | struct snd_ctl_elem_value *ucontrol) | ||
291 | { | ||
292 | struct snd_emu10k1 *emu = snd_kcontrol_chip(kcontrol); | ||
293 | int change = 0; | ||
294 | unsigned int val; | ||
295 | int channel; | ||
296 | |||
297 | channel = (kcontrol->private_value) & 0xff; | ||
298 | if (emu->emu1010.input_source[channel] != ucontrol->value.enumerated.item[0]) { | ||
299 | val = emu->emu1010.input_source[channel] = ucontrol->value.enumerated.item[0]; | ||
300 | change = 1; | ||
301 | snd_emu1010_fpga_link_dst_src_write(emu, | ||
302 | emu1010_input_dst[channel], emu1010_src_regs[val]); | ||
303 | } | ||
304 | return change; | ||
305 | } | ||
306 | |||
307 | #define EMU1010_SOURCE_OUTPUT(xname,chid) \ | ||
308 | { \ | ||
309 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, \ | ||
310 | .access = SNDRV_CTL_ELEM_ACCESS_READWRITE, \ | ||
311 | .info = snd_emu1010_input_output_source_info, \ | ||
312 | .get = snd_emu1010_output_source_get, \ | ||
313 | .put = snd_emu1010_output_source_put, \ | ||
314 | .private_value = chid \ | ||
315 | } | ||
316 | |||
317 | static struct snd_kcontrol_new snd_emu1010_output_enum_ctls[] __devinitdata = { | ||
318 | EMU1010_SOURCE_OUTPUT("Playback Dock DAC1 Left", 0), | ||
319 | EMU1010_SOURCE_OUTPUT("Playback Dock DAC1 Right", 1), | ||
320 | EMU1010_SOURCE_OUTPUT("Playback Dock DAC2 Left", 2), | ||
321 | EMU1010_SOURCE_OUTPUT("Playback Dock DAC2 Right", 3), | ||
322 | EMU1010_SOURCE_OUTPUT("Playback Dock DAC3 Left", 4), | ||
323 | EMU1010_SOURCE_OUTPUT("Playback Dock DAC3 Right", 5), | ||
324 | EMU1010_SOURCE_OUTPUT("Playback Dock DAC4 Left", 6), | ||
325 | EMU1010_SOURCE_OUTPUT("Playback Dock DAC4 Right", 7), | ||
326 | EMU1010_SOURCE_OUTPUT("Playback Dock Phones Left", 8), | ||
327 | EMU1010_SOURCE_OUTPUT("Playback Dock Phones Right", 9), | ||
328 | EMU1010_SOURCE_OUTPUT("Playback Dock SPDIF Left", 0xa), | ||
329 | EMU1010_SOURCE_OUTPUT("Playback Dock SPDIF Right", 0xb), | ||
330 | EMU1010_SOURCE_OUTPUT("Playback 1010 SPDIF Left", 0xc), | ||
331 | EMU1010_SOURCE_OUTPUT("Playback 1010 SPDIF Right", 0xd), | ||
332 | EMU1010_SOURCE_OUTPUT("Playback 0202 DAC Left", 0xe), | ||
333 | EMU1010_SOURCE_OUTPUT("Playback 0202 DAC Right", 0xf), | ||
334 | EMU1010_SOURCE_OUTPUT("Playback 1010 ADAT 0", 0x10), | ||
335 | EMU1010_SOURCE_OUTPUT("Playback 1010 ADAT 1", 0x11), | ||
336 | EMU1010_SOURCE_OUTPUT("Playback 1010 ADAT 2", 0x12), | ||
337 | EMU1010_SOURCE_OUTPUT("Playback 1010 ADAT 3", 0x13), | ||
338 | EMU1010_SOURCE_OUTPUT("Playback 1010 ADAT 4", 0x14), | ||
339 | EMU1010_SOURCE_OUTPUT("Playback 1010 ADAT 5", 0x15), | ||
340 | EMU1010_SOURCE_OUTPUT("Playback 1010 ADAT 6", 0x16), | ||
341 | EMU1010_SOURCE_OUTPUT("Playback 1010 ADAT 7", 0x17), | ||
342 | }; | ||
343 | |||
344 | #define EMU1010_SOURCE_INPUT(xname,chid) \ | ||
345 | { \ | ||
346 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, \ | ||
347 | .access = SNDRV_CTL_ELEM_ACCESS_READWRITE, \ | ||
348 | .info = snd_emu1010_input_output_source_info, \ | ||
349 | .get = snd_emu1010_input_source_get, \ | ||
350 | .put = snd_emu1010_input_source_put, \ | ||
351 | .private_value = chid \ | ||
352 | } | ||
353 | |||
354 | static struct snd_kcontrol_new snd_emu1010_input_enum_ctls[] __devinitdata = { | ||
355 | EMU1010_SOURCE_INPUT("DSP 0 CAPTURE ENUM", 0), | ||
356 | EMU1010_SOURCE_INPUT("DSP 1 CAPTURE ENUM", 1), | ||
357 | EMU1010_SOURCE_INPUT("DSP 2 CAPTURE ENUM", 2), | ||
358 | EMU1010_SOURCE_INPUT("DSP 3 CAPTURE ENUM", 3), | ||
359 | EMU1010_SOURCE_INPUT("DSP 4 CAPTURE ENUM", 4), | ||
360 | EMU1010_SOURCE_INPUT("DSP 5 CAPTURE ENUM", 5), | ||
361 | EMU1010_SOURCE_INPUT("DSP 6 CAPTURE ENUM", 6), | ||
362 | EMU1010_SOURCE_INPUT("DSP 7 CAPTURE ENUM", 7), | ||
363 | EMU1010_SOURCE_INPUT("DSP 8 CAPTURE ENUM", 8), | ||
364 | EMU1010_SOURCE_INPUT("DSP 9 CAPTURE ENUM", 9), | ||
365 | EMU1010_SOURCE_INPUT("DSP A CAPTURE ENUM", 0xa), | ||
366 | EMU1010_SOURCE_INPUT("DSP B CAPTURE ENUM", 0xb), | ||
367 | EMU1010_SOURCE_INPUT("DSP C CAPTURE ENUM", 0xc), | ||
368 | EMU1010_SOURCE_INPUT("DSP D CAPTURE ENUM", 0xd), | ||
369 | EMU1010_SOURCE_INPUT("DSP E CAPTURE ENUM", 0xe), | ||
370 | EMU1010_SOURCE_INPUT("DSP F CAPTURE ENUM", 0xf), | ||
371 | EMU1010_SOURCE_INPUT("DSP 10 CAPTURE ENUM", 0x10), | ||
372 | EMU1010_SOURCE_INPUT("DSP 11 CAPTURE ENUM", 0x11), | ||
373 | EMU1010_SOURCE_INPUT("DSP 12 CAPTURE ENUM", 0x12), | ||
374 | EMU1010_SOURCE_INPUT("DSP 13 CAPTURE ENUM", 0x13), | ||
375 | EMU1010_SOURCE_INPUT("DSP 14 CAPTURE ENUM", 0x14), | ||
376 | EMU1010_SOURCE_INPUT("DSP 15 CAPTURE ENUM", 0x15), | ||
377 | }; | ||
378 | |||
71 | #if 0 | 379 | #if 0 |
72 | static int snd_audigy_spdif_output_rate_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo) | 380 | static int snd_audigy_spdif_output_rate_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo) |
73 | { | 381 | { |
@@ -1021,7 +1329,7 @@ int __devinit snd_emu10k1_mixer(struct snd_emu10k1 *emu, | |||
1021 | return err; | 1329 | return err; |
1022 | } | 1330 | } |
1023 | 1331 | ||
1024 | if ( emu->card_capabilities->emu1212m) { | 1332 | if ( emu->card_capabilities->emu1010) { |
1025 | ; /* Disable the snd_audigy_spdif_shared_spdif */ | 1333 | ; /* Disable the snd_audigy_spdif_shared_spdif */ |
1026 | } else if (emu->audigy) { | 1334 | } else if (emu->audigy) { |
1027 | if ((kctl = snd_ctl_new1(&snd_audigy_shared_spdif, emu)) == NULL) | 1335 | if ((kctl = snd_ctl_new1(&snd_audigy_shared_spdif, emu)) == NULL) |
@@ -1045,6 +1353,21 @@ int __devinit snd_emu10k1_mixer(struct snd_emu10k1 *emu, | |||
1045 | if ((err = snd_p16v_mixer(emu))) | 1353 | if ((err = snd_p16v_mixer(emu))) |
1046 | return err; | 1354 | return err; |
1047 | } | 1355 | } |
1356 | |||
1357 | if ( emu->card_capabilities->emu1010) { | ||
1358 | int i; | ||
1359 | |||
1360 | for (i = 0; i < ARRAY_SIZE(snd_emu1010_output_enum_ctls); i++) { | ||
1361 | err = snd_ctl_add(card, snd_ctl_new1(&snd_emu1010_output_enum_ctls[i], emu)); | ||
1362 | if (err < 0) | ||
1363 | return err; | ||
1364 | } | ||
1365 | for (i = 0; i < ARRAY_SIZE(snd_emu1010_input_enum_ctls); i++) { | ||
1366 | err = snd_ctl_add(card, snd_ctl_new1(&snd_emu1010_input_enum_ctls[i], emu)); | ||
1367 | if (err < 0) | ||
1368 | return err; | ||
1369 | } | ||
1370 | } | ||
1048 | 1371 | ||
1049 | return 0; | 1372 | return 0; |
1050 | } | 1373 | } |
diff --git a/sound/pci/emu10k1/emupcm.c b/sound/pci/emu10k1/emupcm.c index 717e92ec9e0a..44d098ac86d5 100644 --- a/sound/pci/emu10k1/emupcm.c +++ b/sound/pci/emu10k1/emupcm.c | |||
@@ -147,7 +147,7 @@ static int snd_emu10k1_pcm_channel_alloc(struct snd_emu10k1_pcm * epcm, int voic | |||
147 | 1, | 147 | 1, |
148 | &epcm->extra); | 148 | &epcm->extra); |
149 | if (err < 0) { | 149 | if (err < 0) { |
150 | // printk("pcm_channel_alloc: failed extra: voices=%d, frame=%d\n", voices, frame); | 150 | /* printk("pcm_channel_alloc: failed extra: voices=%d, frame=%d\n", voices, frame); */ |
151 | for (i = 0; i < voices; i++) { | 151 | for (i = 0; i < voices; i++) { |
152 | snd_emu10k1_voice_free(epcm->emu, epcm->voices[i]); | 152 | snd_emu10k1_voice_free(epcm->emu, epcm->voices[i]); |
153 | epcm->voices[i] = NULL; | 153 | epcm->voices[i] = NULL; |
@@ -339,7 +339,7 @@ static void snd_emu10k1_pcm_init_voice(struct snd_emu10k1 *emu, | |||
339 | } | 339 | } |
340 | } | 340 | } |
341 | 341 | ||
342 | // setup routing | 342 | /* setup routing */ |
343 | if (emu->audigy) { | 343 | if (emu->audigy) { |
344 | snd_emu10k1_ptr_write(emu, A_FXRT1, voice, | 344 | snd_emu10k1_ptr_write(emu, A_FXRT1, voice, |
345 | snd_emu10k1_compose_audigy_fxrt1(send_routing)); | 345 | snd_emu10k1_compose_audigy_fxrt1(send_routing)); |
@@ -353,8 +353,8 @@ static void snd_emu10k1_pcm_init_voice(struct snd_emu10k1 *emu, | |||
353 | } else | 353 | } else |
354 | snd_emu10k1_ptr_write(emu, FXRT, voice, | 354 | snd_emu10k1_ptr_write(emu, FXRT, voice, |
355 | snd_emu10k1_compose_send_routing(send_routing)); | 355 | snd_emu10k1_compose_send_routing(send_routing)); |
356 | // Stop CA | 356 | /* Stop CA */ |
357 | // Assumption that PT is already 0 so no harm overwriting | 357 | /* Assumption that PT is already 0 so no harm overwriting */ |
358 | snd_emu10k1_ptr_write(emu, PTRX, voice, (send_amount[0] << 8) | send_amount[1]); | 358 | snd_emu10k1_ptr_write(emu, PTRX, voice, (send_amount[0] << 8) | send_amount[1]); |
359 | snd_emu10k1_ptr_write(emu, DSL, voice, end_addr | (send_amount[3] << 24)); | 359 | snd_emu10k1_ptr_write(emu, DSL, voice, end_addr | (send_amount[3] << 24)); |
360 | snd_emu10k1_ptr_write(emu, PSST, voice, start_addr | (send_amount[2] << 24)); | 360 | snd_emu10k1_ptr_write(emu, PSST, voice, start_addr | (send_amount[2] << 24)); |
@@ -367,14 +367,14 @@ static void snd_emu10k1_pcm_init_voice(struct snd_emu10k1 *emu, | |||
367 | snd_emu10k1_ptr_write(emu, CCCA, voice, (start_addr + ccis) | | 367 | snd_emu10k1_ptr_write(emu, CCCA, voice, (start_addr + ccis) | |
368 | emu10k1_select_interprom(pitch_target) | | 368 | emu10k1_select_interprom(pitch_target) | |
369 | (w_16 ? 0 : CCCA_8BITSELECT)); | 369 | (w_16 ? 0 : CCCA_8BITSELECT)); |
370 | // Clear filter delay memory | 370 | /* Clear filter delay memory */ |
371 | snd_emu10k1_ptr_write(emu, Z1, voice, 0); | 371 | snd_emu10k1_ptr_write(emu, Z1, voice, 0); |
372 | snd_emu10k1_ptr_write(emu, Z2, voice, 0); | 372 | snd_emu10k1_ptr_write(emu, Z2, voice, 0); |
373 | // invalidate maps | 373 | /* invalidate maps */ |
374 | silent_page = ((unsigned int)emu->silent_page.addr << 1) | MAP_PTI_MASK; | 374 | silent_page = ((unsigned int)emu->silent_page.addr << 1) | MAP_PTI_MASK; |
375 | snd_emu10k1_ptr_write(emu, MAPA, voice, silent_page); | 375 | snd_emu10k1_ptr_write(emu, MAPA, voice, silent_page); |
376 | snd_emu10k1_ptr_write(emu, MAPB, voice, silent_page); | 376 | snd_emu10k1_ptr_write(emu, MAPB, voice, silent_page); |
377 | // modulation envelope | 377 | /* modulation envelope */ |
378 | snd_emu10k1_ptr_write(emu, CVCF, voice, 0xffff); | 378 | snd_emu10k1_ptr_write(emu, CVCF, voice, 0xffff); |
379 | snd_emu10k1_ptr_write(emu, VTFT, voice, 0xffff); | 379 | snd_emu10k1_ptr_write(emu, VTFT, voice, 0xffff); |
380 | snd_emu10k1_ptr_write(emu, ATKHLDM, voice, 0); | 380 | snd_emu10k1_ptr_write(emu, ATKHLDM, voice, 0); |
@@ -385,12 +385,12 @@ static void snd_emu10k1_pcm_init_voice(struct snd_emu10k1 *emu, | |||
385 | snd_emu10k1_ptr_write(emu, TREMFRQ, voice, 0); | 385 | snd_emu10k1_ptr_write(emu, TREMFRQ, voice, 0); |
386 | snd_emu10k1_ptr_write(emu, FM2FRQ2, voice, 0); | 386 | snd_emu10k1_ptr_write(emu, FM2FRQ2, voice, 0); |
387 | snd_emu10k1_ptr_write(emu, ENVVAL, voice, 0x8000); | 387 | snd_emu10k1_ptr_write(emu, ENVVAL, voice, 0x8000); |
388 | // volume envelope | 388 | /* volume envelope */ |
389 | snd_emu10k1_ptr_write(emu, ATKHLDV, voice, 0x7f7f); | 389 | snd_emu10k1_ptr_write(emu, ATKHLDV, voice, 0x7f7f); |
390 | snd_emu10k1_ptr_write(emu, ENVVOL, voice, 0x0000); | 390 | snd_emu10k1_ptr_write(emu, ENVVOL, voice, 0x0000); |
391 | // filter envelope | 391 | /* filter envelope */ |
392 | snd_emu10k1_ptr_write(emu, PEFE_FILTERAMOUNT, voice, 0x7f); | 392 | snd_emu10k1_ptr_write(emu, PEFE_FILTERAMOUNT, voice, 0x7f); |
393 | // pitch envelope | 393 | /* pitch envelope */ |
394 | snd_emu10k1_ptr_write(emu, PEFE_PITCHAMOUNT, voice, 0); | 394 | snd_emu10k1_ptr_write(emu, PEFE_PITCHAMOUNT, voice, 0); |
395 | 395 | ||
396 | spin_unlock_irqrestore(&emu->reg_lock, flags); | 396 | spin_unlock_irqrestore(&emu->reg_lock, flags); |
@@ -468,7 +468,7 @@ static int snd_emu10k1_efx_playback_hw_free(struct snd_pcm_substream *substream) | |||
468 | snd_emu10k1_voice_free(epcm->emu, epcm->extra); | 468 | snd_emu10k1_voice_free(epcm->emu, epcm->extra); |
469 | epcm->extra = NULL; | 469 | epcm->extra = NULL; |
470 | } | 470 | } |
471 | for (i=0; i < NUM_EFX_PLAYBACK; i++) { | 471 | for (i = 0; i < NUM_EFX_PLAYBACK; i++) { |
472 | if (epcm->voices[i]) { | 472 | if (epcm->voices[i]) { |
473 | snd_emu10k1_voice_free(epcm->emu, epcm->voices[i]); | 473 | snd_emu10k1_voice_free(epcm->emu, epcm->voices[i]); |
474 | epcm->voices[i] = NULL; | 474 | epcm->voices[i] = NULL; |
@@ -637,7 +637,7 @@ static void snd_emu10k1_playback_invalidate_cache(struct snd_emu10k1 *emu, int e | |||
637 | stereo = (!extra && runtime->channels == 2); | 637 | stereo = (!extra && runtime->channels == 2); |
638 | sample = snd_pcm_format_width(runtime->format) == 16 ? 0 : 0x80808080; | 638 | sample = snd_pcm_format_width(runtime->format) == 16 ? 0 : 0x80808080; |
639 | ccis = emu10k1_ccis(stereo, sample == 0); | 639 | ccis = emu10k1_ccis(stereo, sample == 0); |
640 | // set cs to 2 * number of cache registers beside the invalidated | 640 | /* set cs to 2 * number of cache registers beside the invalidated */ |
641 | cs = (sample == 0) ? (32-ccis) : (64-ccis+1) >> 1; | 641 | cs = (sample == 0) ? (32-ccis) : (64-ccis+1) >> 1; |
642 | if (cs > 16) cs = 16; | 642 | if (cs > 16) cs = 16; |
643 | for (i = 0; i < cs; i++) { | 643 | for (i = 0; i < cs; i++) { |
@@ -646,14 +646,14 @@ static void snd_emu10k1_playback_invalidate_cache(struct snd_emu10k1 *emu, int e | |||
646 | snd_emu10k1_ptr_write(emu, CD0 + i, voice + 1, sample); | 646 | snd_emu10k1_ptr_write(emu, CD0 + i, voice + 1, sample); |
647 | } | 647 | } |
648 | } | 648 | } |
649 | // reset cache | 649 | /* reset cache */ |
650 | snd_emu10k1_ptr_write(emu, CCR_CACHEINVALIDSIZE, voice, 0); | 650 | snd_emu10k1_ptr_write(emu, CCR_CACHEINVALIDSIZE, voice, 0); |
651 | snd_emu10k1_ptr_write(emu, CCR_READADDRESS, voice, cra); | 651 | snd_emu10k1_ptr_write(emu, CCR_READADDRESS, voice, cra); |
652 | if (stereo) { | 652 | if (stereo) { |
653 | snd_emu10k1_ptr_write(emu, CCR_CACHEINVALIDSIZE, voice + 1, 0); | 653 | snd_emu10k1_ptr_write(emu, CCR_CACHEINVALIDSIZE, voice + 1, 0); |
654 | snd_emu10k1_ptr_write(emu, CCR_READADDRESS, voice + 1, cra); | 654 | snd_emu10k1_ptr_write(emu, CCR_READADDRESS, voice + 1, cra); |
655 | } | 655 | } |
656 | // fill cache | 656 | /* fill cache */ |
657 | snd_emu10k1_ptr_write(emu, CCR_CACHEINVALIDSIZE, voice, ccis); | 657 | snd_emu10k1_ptr_write(emu, CCR_CACHEINVALIDSIZE, voice, ccis); |
658 | if (stereo) { | 658 | if (stereo) { |
659 | snd_emu10k1_ptr_write(emu, CCR_CACHEINVALIDSIZE, voice+1, ccis); | 659 | snd_emu10k1_ptr_write(emu, CCR_CACHEINVALIDSIZE, voice+1, ccis); |
@@ -732,7 +732,7 @@ static int snd_emu10k1_playback_trigger(struct snd_pcm_substream *substream, | |||
732 | struct snd_emu10k1_pcm_mixer *mix; | 732 | struct snd_emu10k1_pcm_mixer *mix; |
733 | int result = 0; | 733 | int result = 0; |
734 | 734 | ||
735 | // printk("trigger - emu10k1 = 0x%x, cmd = %i, pointer = %i\n", (int)emu, cmd, substream->ops->pointer(substream)); | 735 | /* printk("trigger - emu10k1 = 0x%x, cmd = %i, pointer = %i\n", (int)emu, cmd, substream->ops->pointer(substream)); */ |
736 | spin_lock(&emu->reg_lock); | 736 | spin_lock(&emu->reg_lock); |
737 | switch (cmd) { | 737 | switch (cmd) { |
738 | case SNDRV_PCM_TRIGGER_START: | 738 | case SNDRV_PCM_TRIGGER_START: |
@@ -778,10 +778,10 @@ static int snd_emu10k1_capture_trigger(struct snd_pcm_substream *substream, | |||
778 | switch (cmd) { | 778 | switch (cmd) { |
779 | case SNDRV_PCM_TRIGGER_START: | 779 | case SNDRV_PCM_TRIGGER_START: |
780 | case SNDRV_PCM_TRIGGER_RESUME: | 780 | case SNDRV_PCM_TRIGGER_RESUME: |
781 | // hmm this should cause full and half full interrupt to be raised? | 781 | /* hmm this should cause full and half full interrupt to be raised? */ |
782 | outl(epcm->capture_ipr, emu->port + IPR); | 782 | outl(epcm->capture_ipr, emu->port + IPR); |
783 | snd_emu10k1_intr_enable(emu, epcm->capture_inte); | 783 | snd_emu10k1_intr_enable(emu, epcm->capture_inte); |
784 | // printk("adccr = 0x%x, adcbs = 0x%x\n", epcm->adccr, epcm->adcbs); | 784 | /* printk("adccr = 0x%x, adcbs = 0x%x\n", epcm->adccr, epcm->adcbs); */ |
785 | switch (epcm->type) { | 785 | switch (epcm->type) { |
786 | case CAPTURE_AC97ADC: | 786 | case CAPTURE_AC97ADC: |
787 | snd_emu10k1_ptr_write(emu, ADCCR, 0, epcm->capture_cr_val); | 787 | snd_emu10k1_ptr_write(emu, ADCCR, 0, epcm->capture_cr_val); |
@@ -790,6 +790,7 @@ static int snd_emu10k1_capture_trigger(struct snd_pcm_substream *substream, | |||
790 | if (emu->audigy) { | 790 | if (emu->audigy) { |
791 | snd_emu10k1_ptr_write(emu, A_FXWC1, 0, epcm->capture_cr_val); | 791 | snd_emu10k1_ptr_write(emu, A_FXWC1, 0, epcm->capture_cr_val); |
792 | snd_emu10k1_ptr_write(emu, A_FXWC2, 0, epcm->capture_cr_val2); | 792 | snd_emu10k1_ptr_write(emu, A_FXWC2, 0, epcm->capture_cr_val2); |
793 | snd_printdd("cr_val=0x%x, cr_val2=0x%x\n", epcm->capture_cr_val, epcm->capture_cr_val2); | ||
793 | } else | 794 | } else |
794 | snd_emu10k1_ptr_write(emu, FXWC, 0, epcm->capture_cr_val); | 795 | snd_emu10k1_ptr_write(emu, FXWC, 0, epcm->capture_cr_val); |
795 | break; | 796 | break; |
@@ -851,7 +852,7 @@ static snd_pcm_uframes_t snd_emu10k1_playback_pointer(struct snd_pcm_substream * | |||
851 | ptr -= runtime->buffer_size; | 852 | ptr -= runtime->buffer_size; |
852 | } | 853 | } |
853 | #endif | 854 | #endif |
854 | // printk("ptr = 0x%x, buffer_size = 0x%x, period_size = 0x%x\n", ptr, runtime->buffer_size, runtime->period_size); | 855 | /* printk("ptr = 0x%x, buffer_size = 0x%x, period_size = 0x%x\n", ptr, runtime->buffer_size, runtime->period_size); */ |
855 | return ptr; | 856 | return ptr; |
856 | } | 857 | } |
857 | 858 | ||
@@ -868,7 +869,7 @@ static int snd_emu10k1_efx_playback_trigger(struct snd_pcm_substream *substream, | |||
868 | spin_lock(&emu->reg_lock); | 869 | spin_lock(&emu->reg_lock); |
869 | switch (cmd) { | 870 | switch (cmd) { |
870 | case SNDRV_PCM_TRIGGER_START: | 871 | case SNDRV_PCM_TRIGGER_START: |
871 | // prepare voices | 872 | /* prepare voices */ |
872 | for (i = 0; i < NUM_EFX_PLAYBACK; i++) { | 873 | for (i = 0; i < NUM_EFX_PLAYBACK; i++) { |
873 | snd_emu10k1_playback_invalidate_cache(emu, 0, epcm->voices[i]); | 874 | snd_emu10k1_playback_invalidate_cache(emu, 0, epcm->voices[i]); |
874 | } | 875 | } |
@@ -917,7 +918,7 @@ static snd_pcm_uframes_t snd_emu10k1_capture_pointer(struct snd_pcm_substream *s | |||
917 | if (!epcm->running) | 918 | if (!epcm->running) |
918 | return 0; | 919 | return 0; |
919 | if (epcm->first_ptr) { | 920 | if (epcm->first_ptr) { |
920 | udelay(50); // hack, it takes awhile until capture is started | 921 | udelay(50); /* hack, it takes awhile until capture is started */ |
921 | epcm->first_ptr = 0; | 922 | epcm->first_ptr = 0; |
922 | } | 923 | } |
923 | ptr = snd_emu10k1_ptr_read(emu, epcm->capture_idx_reg, 0) & 0x0000ffff; | 924 | ptr = snd_emu10k1_ptr_read(emu, epcm->capture_idx_reg, 0) & 0x0000ffff; |
@@ -972,6 +973,28 @@ static struct snd_pcm_hardware snd_emu10k1_capture = | |||
972 | .fifo_size = 0, | 973 | .fifo_size = 0, |
973 | }; | 974 | }; |
974 | 975 | ||
976 | static struct snd_pcm_hardware snd_emu10k1_capture_efx = | ||
977 | { | ||
978 | .info = (SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED | | ||
979 | SNDRV_PCM_INFO_BLOCK_TRANSFER | | ||
980 | SNDRV_PCM_INFO_RESUME | | ||
981 | SNDRV_PCM_INFO_MMAP_VALID), | ||
982 | .formats = SNDRV_PCM_FMTBIT_S16_LE, | ||
983 | .rates = SNDRV_PCM_RATE_44100 | SNDRV_PCM_RATE_48000 | | ||
984 | SNDRV_PCM_RATE_88200 | SNDRV_PCM_RATE_96000 | | ||
985 | SNDRV_PCM_RATE_176400 | SNDRV_PCM_RATE_192000, | ||
986 | .rate_min = 44100, | ||
987 | .rate_max = 192000, | ||
988 | .channels_min = 8, | ||
989 | .channels_max = 8, | ||
990 | .buffer_bytes_max = (64*1024), | ||
991 | .period_bytes_min = 384, | ||
992 | .period_bytes_max = (64*1024), | ||
993 | .periods_min = 2, | ||
994 | .periods_max = 2, | ||
995 | .fifo_size = 0, | ||
996 | }; | ||
997 | |||
975 | /* | 998 | /* |
976 | * | 999 | * |
977 | */ | 1000 | */ |
@@ -1016,7 +1039,7 @@ static int snd_emu10k1_efx_playback_close(struct snd_pcm_substream *substream) | |||
1016 | struct snd_emu10k1_pcm_mixer *mix; | 1039 | struct snd_emu10k1_pcm_mixer *mix; |
1017 | int i; | 1040 | int i; |
1018 | 1041 | ||
1019 | for (i=0; i < NUM_EFX_PLAYBACK; i++) { | 1042 | for (i = 0; i < NUM_EFX_PLAYBACK; i++) { |
1020 | mix = &emu->efx_pcm_mixer[i]; | 1043 | mix = &emu->efx_pcm_mixer[i]; |
1021 | mix->epcm = NULL; | 1044 | mix->epcm = NULL; |
1022 | snd_emu10k1_pcm_efx_mixer_notify(emu, i, 0); | 1045 | snd_emu10k1_pcm_efx_mixer_notify(emu, i, 0); |
@@ -1045,7 +1068,7 @@ static int snd_emu10k1_efx_playback_open(struct snd_pcm_substream *substream) | |||
1045 | runtime->private_free = snd_emu10k1_pcm_free_substream; | 1068 | runtime->private_free = snd_emu10k1_pcm_free_substream; |
1046 | runtime->hw = snd_emu10k1_efx_playback; | 1069 | runtime->hw = snd_emu10k1_efx_playback; |
1047 | 1070 | ||
1048 | for (i=0; i < NUM_EFX_PLAYBACK; i++) { | 1071 | for (i = 0; i < NUM_EFX_PLAYBACK; i++) { |
1049 | mix = &emu->efx_pcm_mixer[i]; | 1072 | mix = &emu->efx_pcm_mixer[i]; |
1050 | mix->send_routing[0][0] = i; | 1073 | mix->send_routing[0][0] = i; |
1051 | memset(&mix->send_volume, 0, sizeof(mix->send_volume)); | 1074 | memset(&mix->send_volume, 0, sizeof(mix->send_volume)); |
@@ -1199,15 +1222,59 @@ static int snd_emu10k1_capture_efx_open(struct snd_pcm_substream *substream) | |||
1199 | epcm->capture_idx_reg = FXIDX; | 1222 | epcm->capture_idx_reg = FXIDX; |
1200 | substream->runtime->private_data = epcm; | 1223 | substream->runtime->private_data = epcm; |
1201 | substream->runtime->private_free = snd_emu10k1_pcm_free_substream; | 1224 | substream->runtime->private_free = snd_emu10k1_pcm_free_substream; |
1202 | runtime->hw = snd_emu10k1_capture; | 1225 | runtime->hw = snd_emu10k1_capture_efx; |
1203 | runtime->hw.rates = SNDRV_PCM_RATE_48000; | 1226 | runtime->hw.rates = SNDRV_PCM_RATE_48000; |
1204 | runtime->hw.rate_min = runtime->hw.rate_max = 48000; | 1227 | runtime->hw.rate_min = runtime->hw.rate_max = 48000; |
1205 | spin_lock_irq(&emu->reg_lock); | 1228 | spin_lock_irq(&emu->reg_lock); |
1206 | runtime->hw.channels_min = runtime->hw.channels_max = 0; | 1229 | if (emu->card_capabilities->emu1010) { |
1207 | for (idx = 0; idx < nefx; idx++) { | 1230 | /* TODO |
1208 | if (emu->efx_voices_mask[idx/32] & (1 << (idx%32))) { | 1231 | * SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S32_LE |
1209 | runtime->hw.channels_min++; | 1232 | * SNDRV_PCM_RATE_44100 | SNDRV_PCM_RATE_48000 | |
1210 | runtime->hw.channels_max++; | 1233 | * SNDRV_PCM_RATE_88200 | SNDRV_PCM_RATE_96000 | |
1234 | * SNDRV_PCM_RATE_176400 | SNDRV_PCM_RATE_192000 | ||
1235 | * rate_min = 44100, | ||
1236 | * rate_max = 192000, | ||
1237 | * channels_min = 8, | ||
1238 | * channels_max = 8, | ||
1239 | * Need to add mixer control to fix sample rate | ||
1240 | * | ||
1241 | * There are 16 mono channels of 16bits each. | ||
1242 | * 24bit Audio uses 2x channels over 16bit | ||
1243 | * 96kHz uses 2x channels over 48kHz | ||
1244 | * 192kHz uses 4x channels over 48kHz | ||
1245 | * So, for 48kHz 24bit, one has 8 channels | ||
1246 | * for 96kHz 24bit, one has 4 channels | ||
1247 | * for 192kHz 24bit, one has 2 channels | ||
1248 | */ | ||
1249 | #if 1 | ||
1250 | /* For 48kHz */ | ||
1251 | runtime->hw.rates = SNDRV_PCM_RATE_48000; | ||
1252 | runtime->hw.rate_min = runtime->hw.rate_max = 48000; | ||
1253 | runtime->hw.channels_min = runtime->hw.channels_max = 8; | ||
1254 | #endif | ||
1255 | #if 0 | ||
1256 | /* For 96kHz */ | ||
1257 | runtime->hw.rates = SNDRV_PCM_RATE_96000; | ||
1258 | runtime->hw.rate_min = runtime->hw.rate_max = 96000; | ||
1259 | runtime->hw.channels_min = runtime->hw.channels_max = 4; | ||
1260 | #endif | ||
1261 | #if 0 | ||
1262 | /* For 192kHz */ | ||
1263 | runtime->hw.rates = SNDRV_PCM_RATE_192000; | ||
1264 | runtime->hw.rate_min = runtime->hw.rate_max = 192000; | ||
1265 | runtime->hw.channels_min = runtime->hw.channels_max = 2; | ||
1266 | #endif | ||
1267 | runtime->hw.formats = SNDRV_PCM_FMTBIT_S32_LE; | ||
1268 | /* efx_voices_mask[0] is expected to be zero | ||
1269 | * efx_voices_mask[1] is expected to have 16bits set | ||
1270 | */ | ||
1271 | } else { | ||
1272 | runtime->hw.channels_min = runtime->hw.channels_max = 0; | ||
1273 | for (idx = 0; idx < nefx; idx++) { | ||
1274 | if (emu->efx_voices_mask[idx/32] & (1 << (idx%32))) { | ||
1275 | runtime->hw.channels_min++; | ||
1276 | runtime->hw.channels_max++; | ||
1277 | } | ||
1211 | } | 1278 | } |
1212 | } | 1279 | } |
1213 | epcm->capture_cr_val = emu->efx_voices_mask[0]; | 1280 | epcm->capture_cr_val = emu->efx_voices_mask[0]; |
@@ -1460,7 +1527,7 @@ static void snd_emu10k1_fx8010_playback_tram_poke1(unsigned short *dst_left, | |||
1460 | unsigned int count, | 1527 | unsigned int count, |
1461 | unsigned int tram_shift) | 1528 | unsigned int tram_shift) |
1462 | { | 1529 | { |
1463 | // printk("tram_poke1: dst_left = 0x%p, dst_right = 0x%p, src = 0x%p, count = 0x%x\n", dst_left, dst_right, src, count); | 1530 | /* printk("tram_poke1: dst_left = 0x%p, dst_right = 0x%p, src = 0x%p, count = 0x%x\n", dst_left, dst_right, src, count); */ |
1464 | if ((tram_shift & 1) == 0) { | 1531 | if ((tram_shift & 1) == 0) { |
1465 | while (count--) { | 1532 | while (count--) { |
1466 | *dst_left-- = *src++; | 1533 | *dst_left-- = *src++; |
@@ -1537,7 +1604,7 @@ static int snd_emu10k1_fx8010_playback_prepare(struct snd_pcm_substream *substre | |||
1537 | struct snd_emu10k1_fx8010_pcm *pcm = &emu->fx8010.pcm[substream->number]; | 1604 | struct snd_emu10k1_fx8010_pcm *pcm = &emu->fx8010.pcm[substream->number]; |
1538 | unsigned int i; | 1605 | unsigned int i; |
1539 | 1606 | ||
1540 | // printk("prepare: etram_pages = 0x%p, dma_area = 0x%x, buffer_size = 0x%x (0x%x)\n", emu->fx8010.etram_pages, runtime->dma_area, runtime->buffer_size, runtime->buffer_size << 2); | 1607 | /* printk("prepare: etram_pages = 0x%p, dma_area = 0x%x, buffer_size = 0x%x (0x%x)\n", emu->fx8010.etram_pages, runtime->dma_area, runtime->buffer_size, runtime->buffer_size << 2); */ |
1541 | memset(&pcm->pcm_rec, 0, sizeof(pcm->pcm_rec)); | 1608 | memset(&pcm->pcm_rec, 0, sizeof(pcm->pcm_rec)); |
1542 | pcm->pcm_rec.hw_buffer_size = pcm->buffer_size * 2; /* byte size */ | 1609 | pcm->pcm_rec.hw_buffer_size = pcm->buffer_size * 2; /* byte size */ |
1543 | pcm->pcm_rec.sw_buffer_size = snd_pcm_lib_buffer_bytes(substream); | 1610 | pcm->pcm_rec.sw_buffer_size = snd_pcm_lib_buffer_bytes(substream); |
diff --git a/sound/pci/emu10k1/emuproc.c b/sound/pci/emu10k1/emuproc.c index b939e03aaedf..2c1585991bc8 100644 --- a/sound/pci/emu10k1/emuproc.c +++ b/sound/pci/emu10k1/emuproc.c | |||
@@ -3,6 +3,9 @@ | |||
3 | * Creative Labs, Inc. | 3 | * Creative Labs, Inc. |
4 | * Routines for control of EMU10K1 chips / proc interface routines | 4 | * Routines for control of EMU10K1 chips / proc interface routines |
5 | * | 5 | * |
6 | * Copyright (c) by James Courtier-Dutton <James@superbug.co.uk> | ||
7 | * Added EMU 1010 support. | ||
8 | * | ||
6 | * BUGS: | 9 | * BUGS: |
7 | * -- | 10 | * -- |
8 | * | 11 | * |
@@ -255,7 +258,7 @@ static void snd_emu10k1_proc_rates_read(struct snd_info_entry *entry, | |||
255 | unsigned int val, tmp, n; | 258 | unsigned int val, tmp, n; |
256 | val = snd_emu10k1_ptr20_read(emu, CAPTURE_RATE_STATUS, 0); | 259 | val = snd_emu10k1_ptr20_read(emu, CAPTURE_RATE_STATUS, 0); |
257 | tmp = (val >> 16) & 0x8; | 260 | tmp = (val >> 16) & 0x8; |
258 | for (n=0;n<4;n++) { | 261 | for (n = 0; n < 4; n++) { |
259 | tmp = val >> (16 + (n*4)); | 262 | tmp = val >> (16 + (n*4)); |
260 | if (tmp & 0x8) snd_iprintf(buffer, "Channel %d: Rate=%d\n", n, samplerate[tmp & 0x7]); | 263 | if (tmp & 0x8) snd_iprintf(buffer, "Channel %d: Rate=%d\n", n, samplerate[tmp & 0x7]); |
261 | else snd_iprintf(buffer, "Channel %d: No input\n", n); | 264 | else snd_iprintf(buffer, "Channel %d: No input\n", n); |
@@ -372,6 +375,27 @@ static void snd_emu10k1_proc_voices_read(struct snd_info_entry *entry, | |||
372 | } | 375 | } |
373 | 376 | ||
374 | #ifdef CONFIG_SND_DEBUG | 377 | #ifdef CONFIG_SND_DEBUG |
378 | static void snd_emu_proc_emu1010_reg_read(struct snd_info_entry *entry, | ||
379 | struct snd_info_buffer *buffer) | ||
380 | { | ||
381 | struct snd_emu10k1 *emu = entry->private_data; | ||
382 | unsigned long value; | ||
383 | unsigned long flags; | ||
384 | unsigned long regs; | ||
385 | int i; | ||
386 | snd_iprintf(buffer, "EMU1010 Registers:\n\n"); | ||
387 | |||
388 | for(i = 0; i < 0x30; i+=1) { | ||
389 | spin_lock_irqsave(&emu->emu_lock, flags); | ||
390 | regs=i+0x40; /* 0x40 upwards are registers. */ | ||
391 | outl(regs, emu->port + A_IOCFG); | ||
392 | outl(regs | 0x80, emu->port + A_IOCFG); /* High bit clocks the value into the fpga. */ | ||
393 | value = inl(emu->port + A_IOCFG); | ||
394 | spin_unlock_irqrestore(&emu->emu_lock, flags); | ||
395 | snd_iprintf(buffer, "%02X: %08lX, %02lX\n", i, value, (value >> 8) & 0x7f); | ||
396 | } | ||
397 | } | ||
398 | |||
375 | static void snd_emu_proc_io_reg_read(struct snd_info_entry *entry, | 399 | static void snd_emu_proc_io_reg_read(struct snd_info_entry *entry, |
376 | struct snd_info_buffer *buffer) | 400 | struct snd_info_buffer *buffer) |
377 | { | 401 | { |
@@ -398,7 +422,7 @@ static void snd_emu_proc_io_reg_write(struct snd_info_entry *entry, | |||
398 | while (!snd_info_get_line(buffer, line, sizeof(line))) { | 422 | while (!snd_info_get_line(buffer, line, sizeof(line))) { |
399 | if (sscanf(line, "%x %x", ®, &val) != 2) | 423 | if (sscanf(line, "%x %x", ®, &val) != 2) |
400 | continue; | 424 | continue; |
401 | if ((reg < 0x40) && (reg >=0) && (val <= 0xffffffff) ) { | 425 | if ((reg < 0x40) && (reg >= 0) && (val <= 0xffffffff) ) { |
402 | spin_lock_irqsave(&emu->emu_lock, flags); | 426 | spin_lock_irqsave(&emu->emu_lock, flags); |
403 | outl(val, emu->port + (reg & 0xfffffffc)); | 427 | outl(val, emu->port + (reg & 0xfffffffc)); |
404 | spin_unlock_irqrestore(&emu->emu_lock, flags); | 428 | spin_unlock_irqrestore(&emu->emu_lock, flags); |
@@ -474,7 +498,7 @@ static void snd_emu_proc_ptr_reg_write(struct snd_info_entry *entry, | |||
474 | while (!snd_info_get_line(buffer, line, sizeof(line))) { | 498 | while (!snd_info_get_line(buffer, line, sizeof(line))) { |
475 | if (sscanf(line, "%x %x %x", ®, &channel_id, &val) != 3) | 499 | if (sscanf(line, "%x %x %x", ®, &channel_id, &val) != 3) |
476 | continue; | 500 | continue; |
477 | if ((reg < 0xa0) && (reg >=0) && (val <= 0xffffffff) && (channel_id >=0) && (channel_id <= 3) ) | 501 | if ((reg < 0xa0) && (reg >= 0) && (val <= 0xffffffff) && (channel_id >= 0) && (channel_id <= 3) ) |
478 | snd_ptr_write(emu, iobase, reg, channel_id, val); | 502 | snd_ptr_write(emu, iobase, reg, channel_id, val); |
479 | } | 503 | } |
480 | } | 504 | } |
@@ -531,6 +555,10 @@ int __devinit snd_emu10k1_proc_init(struct snd_emu10k1 * emu) | |||
531 | { | 555 | { |
532 | struct snd_info_entry *entry; | 556 | struct snd_info_entry *entry; |
533 | #ifdef CONFIG_SND_DEBUG | 557 | #ifdef CONFIG_SND_DEBUG |
558 | if ((emu->card_capabilities->emu1010) && | ||
559 | snd_card_proc_new(emu->card, "emu1010_regs", &entry)) { | ||
560 | snd_info_set_text_ops(entry, emu, snd_emu_proc_emu1010_reg_read); | ||
561 | } | ||
534 | if (! snd_card_proc_new(emu->card, "io_regs", &entry)) { | 562 | if (! snd_card_proc_new(emu->card, "io_regs", &entry)) { |
535 | snd_info_set_text_ops(entry, emu, snd_emu_proc_io_reg_read); | 563 | snd_info_set_text_ops(entry, emu, snd_emu_proc_io_reg_read); |
536 | entry->c.text.write = snd_emu_proc_io_reg_write; | 564 | entry->c.text.write = snd_emu_proc_io_reg_write; |
diff --git a/sound/pci/emu10k1/io.c b/sound/pci/emu10k1/io.c index 029e7856c43b..27ab7d1788a0 100644 --- a/sound/pci/emu10k1/io.c +++ b/sound/pci/emu10k1/io.c | |||
@@ -167,6 +167,51 @@ int snd_emu10k1_spi_write(struct snd_emu10k1 * emu, | |||
167 | return 0; | 167 | return 0; |
168 | } | 168 | } |
169 | 169 | ||
170 | int snd_emu1010_fpga_write(struct snd_emu10k1 * emu, int reg, int value) | ||
171 | { | ||
172 | if (reg < 0 || reg > 0x3f) | ||
173 | return 1; | ||
174 | reg += 0x40; /* 0x40 upwards are registers. */ | ||
175 | if (value < 0 || value > 0x3f) /* 0 to 0x3f are values */ | ||
176 | return 1; | ||
177 | outl(reg, emu->port + A_IOCFG); | ||
178 | udelay(10); | ||
179 | outl(reg | 0x80, emu->port + A_IOCFG); /* High bit clocks the value into the fpga. */ | ||
180 | udelay(10); | ||
181 | outl(value, emu->port + A_IOCFG); | ||
182 | udelay(10); | ||
183 | outl(value | 0x80 , emu->port + A_IOCFG); /* High bit clocks the value into the fpga. */ | ||
184 | |||
185 | return 0; | ||
186 | } | ||
187 | |||
188 | int snd_emu1010_fpga_read(struct snd_emu10k1 * emu, int reg, int *value) | ||
189 | { | ||
190 | if (reg < 0 || reg > 0x3f) | ||
191 | return 1; | ||
192 | reg += 0x40; /* 0x40 upwards are registers. */ | ||
193 | outl(reg, emu->port + A_IOCFG); | ||
194 | udelay(10); | ||
195 | outl(reg | 0x80, emu->port + A_IOCFG); /* High bit clocks the value into the fpga. */ | ||
196 | udelay(10); | ||
197 | *value = ((inl(emu->port + A_IOCFG) >> 8) & 0x7f); | ||
198 | |||
199 | return 0; | ||
200 | } | ||
201 | |||
202 | /* Each Destination has one and only one Source, | ||
203 | * but one Source can feed any number of Destinations simultaneously. | ||
204 | */ | ||
205 | int snd_emu1010_fpga_link_dst_src_write(struct snd_emu10k1 * emu, int dst, int src) | ||
206 | { | ||
207 | snd_emu1010_fpga_write(emu, 0x00, ((dst >> 8) & 0x3f) ); | ||
208 | snd_emu1010_fpga_write(emu, 0x01, (dst & 0x3f) ); | ||
209 | snd_emu1010_fpga_write(emu, 0x02, ((src >> 8) & 0x3f) ); | ||
210 | snd_emu1010_fpga_write(emu, 0x03, (src & 0x3f) ); | ||
211 | |||
212 | return 0; | ||
213 | } | ||
214 | |||
170 | void snd_emu10k1_intr_enable(struct snd_emu10k1 *emu, unsigned int intrenb) | 215 | void snd_emu10k1_intr_enable(struct snd_emu10k1 *emu, unsigned int intrenb) |
171 | { | 216 | { |
172 | unsigned long flags; | 217 | unsigned long flags; |
diff --git a/sound/pci/emu10k1/p16v.c b/sound/pci/emu10k1/p16v.c index 4e0f95438f47..5da637c73393 100644 --- a/sound/pci/emu10k1/p16v.c +++ b/sound/pci/emu10k1/p16v.c | |||
@@ -253,7 +253,7 @@ static int snd_p16v_pcm_close_playback(struct snd_pcm_substream *substream) | |||
253 | struct snd_emu10k1 *emu = snd_pcm_substream_chip(substream); | 253 | struct snd_emu10k1 *emu = snd_pcm_substream_chip(substream); |
254 | //struct snd_pcm_runtime *runtime = substream->runtime; | 254 | //struct snd_pcm_runtime *runtime = substream->runtime; |
255 | //struct snd_emu10k1_pcm *epcm = runtime->private_data; | 255 | //struct snd_emu10k1_pcm *epcm = runtime->private_data; |
256 | emu->p16v_voices[substream->pcm->device - emu->p16v_device_offset].use=0; | 256 | emu->p16v_voices[substream->pcm->device - emu->p16v_device_offset].use = 0; |
257 | /* FIXME: maybe zero others */ | 257 | /* FIXME: maybe zero others */ |
258 | return 0; | 258 | return 0; |
259 | } | 259 | } |
@@ -264,7 +264,7 @@ static int snd_p16v_pcm_close_capture(struct snd_pcm_substream *substream) | |||
264 | struct snd_emu10k1 *emu = snd_pcm_substream_chip(substream); | 264 | struct snd_emu10k1 *emu = snd_pcm_substream_chip(substream); |
265 | //struct snd_pcm_runtime *runtime = substream->runtime; | 265 | //struct snd_pcm_runtime *runtime = substream->runtime; |
266 | //struct snd_emu10k1_pcm *epcm = runtime->private_data; | 266 | //struct snd_emu10k1_pcm *epcm = runtime->private_data; |
267 | emu->p16v_capture_voice.use=0; | 267 | emu->p16v_capture_voice.use = 0; |
268 | /* FIXME: maybe zero others */ | 268 | /* FIXME: maybe zero others */ |
269 | return 0; | 269 | return 0; |
270 | } | 270 | } |
@@ -349,7 +349,7 @@ static int snd_p16v_pcm_prepare_playback(struct snd_pcm_substream *substream) | |||
349 | break; | 349 | break; |
350 | } | 350 | } |
351 | /* FIXME: Check emu->buffer.size before actually writing to it. */ | 351 | /* FIXME: Check emu->buffer.size before actually writing to it. */ |
352 | for(i=0; i < runtime->periods; i++) { | 352 | for(i = 0; i < runtime->periods; i++) { |
353 | table_base[i*2]=runtime->dma_addr+(i*period_size_bytes); | 353 | table_base[i*2]=runtime->dma_addr+(i*period_size_bytes); |
354 | table_base[(i*2)+1]=period_size_bytes<<16; | 354 | table_base[(i*2)+1]=period_size_bytes<<16; |
355 | } | 355 | } |
@@ -394,7 +394,7 @@ static int snd_p16v_pcm_prepare_capture(struct snd_pcm_substream *substream) | |||
394 | /* FIXME: Check emu->buffer.size before actually writing to it. */ | 394 | /* FIXME: Check emu->buffer.size before actually writing to it. */ |
395 | snd_emu10k1_ptr20_write(emu, 0x13, channel, 0); | 395 | snd_emu10k1_ptr20_write(emu, 0x13, channel, 0); |
396 | snd_emu10k1_ptr20_write(emu, CAPTURE_DMA_ADDR, channel, runtime->dma_addr); | 396 | snd_emu10k1_ptr20_write(emu, CAPTURE_DMA_ADDR, channel, runtime->dma_addr); |
397 | snd_emu10k1_ptr20_write(emu, CAPTURE_BUFFER_SIZE, channel, frames_to_bytes(runtime, runtime->buffer_size)<<16); // buffer size in bytes | 397 | snd_emu10k1_ptr20_write(emu, CAPTURE_BUFFER_SIZE, channel, frames_to_bytes(runtime, runtime->buffer_size) << 16); // buffer size in bytes |
398 | snd_emu10k1_ptr20_write(emu, CAPTURE_POINTER, channel, 0); | 398 | snd_emu10k1_ptr20_write(emu, CAPTURE_POINTER, channel, 0); |
399 | //snd_emu10k1_ptr20_write(emu, CAPTURE_SOURCE, 0x0, 0x333300e4); /* Select MIC or Line in */ | 399 | //snd_emu10k1_ptr20_write(emu, CAPTURE_SOURCE, 0x0, 0x333300e4); /* Select MIC or Line in */ |
400 | //snd_emu10k1_ptr20_write(emu, EXTENDED_INT_MASK, 0, snd_emu10k1_ptr20_read(emu, EXTENDED_INT_MASK, 0) | (0x110000<<channel)); | 400 | //snd_emu10k1_ptr20_write(emu, EXTENDED_INT_MASK, 0, snd_emu10k1_ptr20_read(emu, EXTENDED_INT_MASK, 0) | (0x110000<<channel)); |
@@ -437,7 +437,7 @@ static int snd_p16v_pcm_trigger_playback(struct snd_pcm_substream *substream, | |||
437 | struct snd_pcm_substream *s; | 437 | struct snd_pcm_substream *s; |
438 | u32 basic = 0; | 438 | u32 basic = 0; |
439 | u32 inte = 0; | 439 | u32 inte = 0; |
440 | int running=0; | 440 | int running = 0; |
441 | 441 | ||
442 | switch (cmd) { | 442 | switch (cmd) { |
443 | case SNDRV_PCM_TRIGGER_START: | 443 | case SNDRV_PCM_TRIGGER_START: |
@@ -445,7 +445,7 @@ static int snd_p16v_pcm_trigger_playback(struct snd_pcm_substream *substream, | |||
445 | break; | 445 | break; |
446 | case SNDRV_PCM_TRIGGER_STOP: | 446 | case SNDRV_PCM_TRIGGER_STOP: |
447 | default: | 447 | default: |
448 | running=0; | 448 | running = 0; |
449 | break; | 449 | break; |
450 | } | 450 | } |
451 | snd_pcm_group_for_each(pos, substream) { | 451 | snd_pcm_group_for_each(pos, substream) { |
diff --git a/sound/pci/emu10k1/voice.c b/sound/pci/emu10k1/voice.c index 94eca82dd4fc..1db50fe61475 100644 --- a/sound/pci/emu10k1/voice.c +++ b/sound/pci/emu10k1/voice.c | |||
@@ -83,7 +83,7 @@ static int voice_alloc(struct snd_emu10k1 *emu, int type, int number, | |||
83 | if (first_voice == last_voice) | 83 | if (first_voice == last_voice) |
84 | return -ENOMEM; | 84 | return -ENOMEM; |
85 | 85 | ||
86 | for (i=0; i < number; i++) { | 86 | for (i = 0; i < number; i++) { |
87 | voice = &emu->voices[(first_voice + i) % NUM_G]; | 87 | voice = &emu->voices[(first_voice + i) % NUM_G]; |
88 | // printk("voice alloc - %i, %i of %i\n", voice->number, idx-first_voice+1, number); | 88 | // printk("voice alloc - %i, %i of %i\n", voice->number, idx-first_voice+1, number); |
89 | voice->use = 1; | 89 | voice->use = 1; |