diff options
Diffstat (limited to 'sound/pci/emu10k1/emu10k1_main.c')
-rw-r--r-- | sound/pci/emu10k1/emu10k1_main.c | 130 |
1 files changed, 78 insertions, 52 deletions
diff --git a/sound/pci/emu10k1/emu10k1_main.c b/sound/pci/emu10k1/emu10k1_main.c index 69f342ce9b2..da660676680 100644 --- a/sound/pci/emu10k1/emu10k1_main.c +++ b/sound/pci/emu10k1/emu10k1_main.c @@ -54,12 +54,14 @@ #define DOCK_FILENAME "emu/audio_dock.fw" #define EMU1010B_FILENAME "emu/emu1010b.fw" #define MICRO_DOCK_FILENAME "emu/micro_dock.fw" +#define EMU0404_FILENAME "emu/emu0404.fw" #define EMU1010_NOTEBOOK_FILENAME "emu/emu1010_notebook.fw" MODULE_FIRMWARE(HANA_FILENAME); MODULE_FIRMWARE(DOCK_FILENAME); MODULE_FIRMWARE(EMU1010B_FILENAME); MODULE_FIRMWARE(MICRO_DOCK_FILENAME); +MODULE_FIRMWARE(EMU0404_FILENAME); MODULE_FIRMWARE(EMU1010_NOTEBOOK_FILENAME); @@ -287,7 +289,7 @@ static int snd_emu10k1_init(struct snd_emu10k1 *emu, int enable_ir, int resume) snd_emu10k1_ptr_write(emu, MAPB, ch, silent_page); } - if (emu->card_capabilities->emu1010) { + if (emu->card_capabilities->emu_model) { outl(HCFG_AUTOMUTE_ASYNC | HCFG_EMU32_SLAVE | HCFG_AUDIOENABLE, emu->port + HCFG); @@ -317,7 +319,7 @@ static int snd_emu10k1_init(struct snd_emu10k1 *emu, int enable_ir, int resume) outl(HCFG_LOCKTANKCACHE_MASK | HCFG_AUTOMUTE | HCFG_JOYENABLE, emu->port + HCFG); if (enable_ir) { /* enable IR for SB Live */ - if (emu->card_capabilities->emu1010) { + if (emu->card_capabilities->emu_model) { ; /* Disable all access to A_IOCFG for the emu1010 */ } else if (emu->card_capabilities->i2c_adc) { ; /* Disable A_IOCFG for Audigy 2 ZS Notebook */ @@ -338,7 +340,7 @@ static int snd_emu10k1_init(struct snd_emu10k1 *emu, int enable_ir, int resume) } } - if (emu->card_capabilities->emu1010) { + if (emu->card_capabilities->emu_model) { ; /* Disable all access to A_IOCFG for the emu1010 */ } else if (emu->card_capabilities->i2c_adc) { ; /* Disable A_IOCFG for Audigy 2 ZS Notebook */ @@ -358,7 +360,7 @@ static void snd_emu10k1_audio_enable(struct snd_emu10k1 *emu) outl(inl(emu->port + HCFG) | HCFG_AUDIOENABLE, emu->port + HCFG); /* Enable analog/digital outs on audigy */ - if (emu->card_capabilities->emu1010) { + if (emu->card_capabilities->emu_model) { ; /* Disable all access to A_IOCFG for the emu1010 */ } else if (emu->card_capabilities->i2c_adc) { ; /* Disable A_IOCFG for Audigy 2 ZS Notebook */ @@ -660,6 +662,8 @@ static int snd_emu1010_load_firmware(struct snd_emu10k1 * emu, const char * file int n, i; int reg; int value; + unsigned int write_post; + unsigned long flags; const struct firmware *fw_entry; if ((err = request_firmware(&fw_entry, filename, &emu->pci->dev)) != 0) { @@ -667,12 +671,6 @@ static int snd_emu1010_load_firmware(struct snd_emu10k1 * emu, const char * file return err; } snd_printk(KERN_INFO "firmware size=0x%zx\n", fw_entry->size); -#if 0 - if (fw_entry->size != 0x133a4) { - snd_printk(KERN_ERR "firmware: %s wrong size.\n",filename); - return -EINVAL; - } -#endif /* The FPGA is a Xilinx Spartan IIE XC2S50E */ /* GPIO7 -> FPGA PGMN @@ -680,9 +678,12 @@ static int snd_emu1010_load_firmware(struct snd_emu10k1 * emu, const char * file * GPIO5 -> FPGA DIN * FPGA CONFIG OFF -> FPGA PGMN */ + spin_lock_irqsave(&emu->emu_lock, flags); outl(0x00, emu->port + A_IOCFG); /* Set PGMN low for 1uS. */ - udelay(1); + write_post = inl(emu->port + A_IOCFG); + udelay(100); outl(0x80, emu->port + A_IOCFG); /* Leave bit 7 set during netlist setup. */ + write_post = inl(emu->port + A_IOCFG); udelay(100); /* Allow FPGA memory to clean */ for(n = 0; n < fw_entry->size; n++) { value=fw_entry->data[n]; @@ -692,12 +693,15 @@ static int snd_emu1010_load_firmware(struct snd_emu10k1 * emu, const char * file reg = reg | 0x20; value = value >> 1; outl(reg, emu->port + A_IOCFG); + write_post = inl(emu->port + A_IOCFG); outl(reg | 0x40, emu->port + A_IOCFG); + write_post = inl(emu->port + A_IOCFG); } } /* After programming, set GPIO bit 4 high again. */ outl(0x10, emu->port + A_IOCFG); - + write_post = inl(emu->port + A_IOCFG); + spin_unlock_irqrestore(&emu->emu_lock, flags); release_firmware(fw_entry); return 0; @@ -711,7 +715,7 @@ int emu1010_firmware_thread(void *data) { for (;;) { /* Delay to allow Audio Dock to settle */ - msleep(1000); + msleep_interruptible(1000); if (kthread_should_stop()) break; snd_emu1010_fpga_read(emu, EMU_HANA_IRQ_STATUS, &tmp ); /* IRQ Status */ @@ -721,17 +725,17 @@ int emu1010_firmware_thread(void *data) { /* Return to Audio Dock programming mode */ snd_printk(KERN_INFO "emu1010: Loading Audio Dock Firmware\n"); snd_emu1010_fpga_write(emu, EMU_HANA_FPGA_CONFIG, EMU_HANA_FPGA_CONFIG_AUDIODOCK ); - if (emu->card_capabilities->emu1010 == 1) { + if (emu->card_capabilities->emu_model == 1) { if ((err = snd_emu1010_load_firmware(emu, DOCK_FILENAME)) != 0) { - return err; + continue; } - } else if (emu->card_capabilities->emu1010 == 2) { + } else if (emu->card_capabilities->emu_model == 2) { if ((err = snd_emu1010_load_firmware(emu, MICRO_DOCK_FILENAME)) != 0) { - return err; + continue; } - } else if (emu->card_capabilities->emu1010 == 3) { + } else if (emu->card_capabilities->emu_model == 3) { if ((err = snd_emu1010_load_firmware(emu, MICRO_DOCK_FILENAME)) != 0) { - return err; + continue; } } @@ -744,8 +748,7 @@ int emu1010_firmware_thread(void *data) { if ((reg & 0x1f) != 0x15) { /* FPGA failed to be programmed */ snd_printk(KERN_INFO "emu1010: Loading Audio Dock Firmware file failed, reg=0x%x\n", reg); - return 0; - return -ENODEV; + continue; } snd_printk(KERN_INFO "emu1010: Audio Dock Firmware loaded\n"); snd_emu1010_fpga_read(emu, EMU_DOCK_MAJOR_REV, &tmp ); @@ -756,9 +759,9 @@ int emu1010_firmware_thread(void *data) { msleep(10); /* Unmute all. Default is muted after a firmware load */ snd_emu1010_fpga_write(emu, EMU_HANA_UNMUTE, EMU_UNMUTE ); - break; } } + snd_printk(KERN_INFO "emu1010: firmware thread stopping\n"); return 0; } @@ -799,6 +802,7 @@ static int snd_emu10k1_emu1010_init(struct snd_emu10k1 * emu) int tmp,tmp2; int reg; int err; + const char *filename = NULL; snd_printk(KERN_INFO "emu1010: Special config.\n"); /* AC97 2.1, Any 16Meg of 4Gig address, Auto-Mute, EMU32 Slave, @@ -840,21 +844,31 @@ static int snd_emu10k1_emu1010_init(struct snd_emu10k1 * emu) return -ENODEV; } snd_printk(KERN_INFO "emu1010: EMU_HANA_ID=0x%x\n",reg); - if (emu->card_capabilities->emu1010 == 1) { - if ((err = snd_emu1010_load_firmware(emu, HANA_FILENAME)) != 0) { - snd_printk(KERN_INFO "emu1010: Loading Hana Firmware file %s failed\n", HANA_FILENAME); - return err; - } - } else if (emu->card_capabilities->emu1010 == 2) { - if ((err = snd_emu1010_load_firmware(emu, EMU1010B_FILENAME)) != 0) { - snd_printk(KERN_INFO "emu1010: Loading Firmware file %s failed\n", EMU1010B_FILENAME); - return err; - } - } else if (emu->card_capabilities->emu1010 == 3) { - if ((err = snd_emu1010_load_firmware(emu, EMU1010_NOTEBOOK_FILENAME)) != 0) { - snd_printk(KERN_INFO "emu1010: Loading Firmware file %s failed\n", EMU1010_NOTEBOOK_FILENAME); - return err; - } + switch (emu->card_capabilities->emu_model) { + case 1: + filename = HANA_FILENAME; + break; + case 2: + filename = EMU1010B_FILENAME; + break; + case 3: + filename = EMU1010_NOTEBOOK_FILENAME; + break; + case 4: + filename = EMU0404_FILENAME; + break; + default: + filename = NULL; + return -ENODEV; + break; + } + snd_printk(KERN_INFO "emu1010: filename %s testing\n", filename); + err = snd_emu1010_load_firmware(emu, filename); + if (err != 0) { + snd_printk( + KERN_INFO "emu1010: Loading Firmware file %s failed\n", + filename); + return err; } /* ID, should read & 0x7f = 0x55 when FPGA programmed. */ @@ -1201,11 +1215,12 @@ static int snd_emu10k1_free(struct snd_emu10k1 *emu) } snd_emu10k1_free_efx(emu); } - if (emu->card_capabilities->emu1010) { + if (emu->card_capabilities->emu_model == 1) { /* Disable 48Volt power to Audio Dock */ snd_emu1010_fpga_write(emu, EMU_HANA_DOCK_PWR, 0 ); - kthread_stop(emu->emu1010.firmware_thread); } + if (emu->card_capabilities->emu_model) + kthread_stop(emu->emu1010.firmware_thread); if (emu->memhdr) snd_util_memhdr_free(emu->memhdr); if (emu->silent_page.area) @@ -1337,6 +1352,15 @@ static struct snd_emu_chip_details emu_chip_details[] = { .spi_dac = 1, .i2c_adc = 1, .spk71 = 1} , + /* Tested by James@superbug.co.uk 20-3-2007. */ + {.vendor = 0x1102, .device = 0x0008, .subsystem = 0x40021102, + .driver = "Audigy2", .name = "E-mu 0404 [4002]", + .id = "EMU0404", + .emu10k2_chip = 1, + .ca0102_chip = 1, + .spk71 = 1, + .emu_model = 4} , /* EMU 0404 */ + /* Tested by James@superbug.co.uk 4th Nov 2007. */ {.vendor = 0x1102, .device = 0x0008, .subsystem = 0x42011102, .driver = "Audigy2", .name = "E-mu 1010 Notebook [MAEM8950]", .id = "EMU1010", @@ -1344,28 +1368,30 @@ static struct snd_emu_chip_details emu_chip_details[] = { .ca0108_chip = 1, .ca_cardbus_chip = 1, .spk71 = 1 , - .emu1010 = 3} , + .emu_model = 3} , + /* Tested by James@superbug.co.uk 4th Nov 2007. */ {.vendor = 0x1102, .device = 0x0008, .subsystem = 0x40041102, .driver = "Audigy2", .name = "E-mu 1010b PCI [MAEM????]", .id = "EMU1010", .emu10k2_chip = 1, .ca0108_chip = 1, - .spk71 = 1 , - .emu1010 = 2} , + .spk71 = 1, + .emu_model = 2} , + /* Tested by James@superbug.co.uk 8th July 2005. */ + {.vendor = 0x1102, .device = 0x0004, .subsystem = 0x40011102, + .driver = "Audigy2", .name = "E-mu 1010 [4001]", + .id = "EMU1010", + .emu10k2_chip = 1, + .ca0102_chip = 1, + .spk71 = 1, + .emu_model = 1} , /* Emu 1010 */ + /* Audigy4 (Not PRO) SB0610 */ {.vendor = 0x1102, .device = 0x0008, .driver = "Audigy2", .name = "Audigy 2 Value [Unknown]", .id = "Audigy2", .emu10k2_chip = 1, .ca0108_chip = 1, .ac97_chip = 1} , - /* Tested by James@superbug.co.uk 8th July 2005. No sound available yet. */ - {.vendor = 0x1102, .device = 0x0004, .subsystem = 0x40011102, - .driver = "Audigy2", .name = "E-mu 1010 [4001]", - .id = "EMU1010", - .emu10k2_chip = 1, - .ca0102_chip = 1, - .spk71 = 1, - .emu1010 = 1} , /* Tested by James@superbug.co.uk 3rd July 2005 */ {.vendor = 0x1102, .device = 0x0004, .subsystem = 0x20071102, .driver = "Audigy2", .name = "Audigy 4 PRO [SB0380]", @@ -1793,7 +1819,7 @@ int __devinit snd_emu10k1_create(struct snd_card *card, if (emu->card_capabilities->ecard) { if ((err = snd_emu10k1_ecard_init(emu)) < 0) goto error; - } else if (emu->card_capabilities->emu1010) { + } else if (emu->card_capabilities->emu_model) { if ((err = snd_emu10k1_emu1010_init(emu)) < 0) { snd_emu10k1_free(emu); return err; @@ -1942,7 +1968,7 @@ void snd_emu10k1_resume_init(struct snd_emu10k1 *emu) snd_emu10k1_cardbus_init(emu); if (emu->card_capabilities->ecard) snd_emu10k1_ecard_init(emu); - else if (emu->card_capabilities->emu1010) + else if (emu->card_capabilities->emu_model) snd_emu10k1_emu1010_init(emu); else snd_emu10k1_ptr_write(emu, AC97SLOT, 0, AC97SLOT_CNTR|AC97SLOT_LFE); |