forked from torvalds/linux
-
Notifications
You must be signed in to change notification settings - Fork 17
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
[ALSA] snd:emu10k1: E-Mu updates. Fixes to firmware loading and suppo…
…rt for 0404. Signed-off-by: James Courtier-Dutton <[email protected]> Signed-off-by: Jaroslav Kysela <[email protected]>
- Loading branch information
James Courtier-Dutton
authored and
Mercurial server
committed
Jan 31, 2008
1 parent
44893a3
commit 190d2c4
Showing
7 changed files
with
97 additions
and
64 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -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,29 +662,28 @@ 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) { | ||
snd_printk(KERN_ERR "firmware: %s not found. Err=%d\n",filename, err); | ||
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 | ||
* GPIO6 -> FPGA CCLK | ||
* 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,35 +1352,46 @@ static struct snd_emu_chip_details emu_chip_details[] = { | |
.spi_dac = 1, | ||
.i2c_adc = 1, | ||
.spk71 = 1} , | ||
/* Tested by [email protected] 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 [email protected] 4th Nov 2007. */ | ||
{.vendor = 0x1102, .device = 0x0008, .subsystem = 0x42011102, | ||
.driver = "Audigy2", .name = "E-mu 1010 Notebook [MAEM8950]", | ||
.id = "EMU1010", | ||
.emu10k2_chip = 1, | ||
.ca0108_chip = 1, | ||
.ca_cardbus_chip = 1, | ||
.spk71 = 1 , | ||
.emu1010 = 3} , | ||
.emu_model = 3} , | ||
/* Tested by [email protected] 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 [email protected] 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 [email protected] 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 [email protected] 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); | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.