ALSA: emu10k1: Fix dock firmware loading
authorTakashi Iwai <tiwai@suse.de>
Wed, 24 Apr 2013 05:55:20 +0000 (07:55 +0200)
committerTakashi Iwai <tiwai@suse.de>
Wed, 24 Apr 2013 06:11:49 +0000 (08:11 +0200)
The commit [b209c4df: ALSA: emu10k1: cache emu1010 firmware] broke the
firmware loading of the dock, just (mistakenly) ignoring a different
firmware for docks on some models.  This patch revives them again.

Bugzilla: https://bugs.archlinux.org/task/34865
Reported-and-tested-by: Tobias Powalowski <tobias.powalowski@googlemail.com>
Cc: <stable@vger.kernel.org> [v3.8+]
Signed-off-by: Takashi Iwai <tiwai@suse.de>
include/sound/emu10k1.h
sound/pci/emu10k1/emu10k1_main.c

index f841ba4bacb81985f1a52257c8230a22de0333e2..dfb42ca6d0436539ada89bcd063c26e5c4e85d86 100644 (file)
@@ -1787,6 +1787,7 @@ struct snd_emu10k1 {
        unsigned int next_free_voice;
 
        const struct firmware *firmware;
+       const struct firmware *dock_fw;
 
 #ifdef CONFIG_PM_SLEEP
        unsigned int *saved_ptr;
index e6b016693240617451f6720c6f8f4643e8160c67..bdd888ec9a8422838144fd93e8c8b8cff92ee4fe 100644 (file)
@@ -657,14 +657,14 @@ static int snd_emu10k1_cardbus_init(struct snd_emu10k1 *emu)
        return 0;
 }
 
-static int snd_emu1010_load_firmware(struct snd_emu10k1 *emu)
+static int snd_emu1010_load_firmware(struct snd_emu10k1 *emu,
+                                    const struct firmware *fw_entry)
 {
        int n, i;
        int reg;
        int value;
        unsigned int write_post;
        unsigned long flags;
-       const struct firmware *fw_entry = emu->firmware;
 
        if (!fw_entry)
                return -EIO;
@@ -725,9 +725,34 @@ static 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);
-                       err = snd_emu1010_load_firmware(emu);
-                       if (err != 0)
-                               continue;
+
+                       if (!emu->dock_fw) {
+                               const char *filename = NULL;
+                               switch (emu->card_capabilities->emu_model) {
+                               case EMU_MODEL_EMU1010:
+                                       filename = DOCK_FILENAME;
+                                       break;
+                               case EMU_MODEL_EMU1010B:
+                                       filename = MICRO_DOCK_FILENAME;
+                                       break;
+                               case EMU_MODEL_EMU1616:
+                                       filename = MICRO_DOCK_FILENAME;
+                                       break;
+                               }
+                               if (filename) {
+                                       err = request_firmware(&emu->dock_fw,
+                                                              filename,
+                                                              &emu->pci->dev);
+                                       if (err)
+                                               continue;
+                               }
+                       }
+
+                       if (emu->dock_fw) {
+                               err = snd_emu1010_load_firmware(emu, emu->dock_fw);
+                               if (err)
+                                       continue;
+                       }
 
                        snd_emu1010_fpga_write(emu, EMU_HANA_FPGA_CONFIG, 0);
                        snd_emu1010_fpga_read(emu, EMU_HANA_IRQ_STATUS, &reg);
@@ -862,7 +887,7 @@ static int snd_emu10k1_emu1010_init(struct snd_emu10k1 *emu)
                           filename, emu->firmware->size);
        }
 
-       err = snd_emu1010_load_firmware(emu);
+       err = snd_emu1010_load_firmware(emu, emu->firmware);
        if (err != 0) {
                snd_printk(KERN_INFO "emu1010: Loading Firmware failed\n");
                return err;
@@ -1253,6 +1278,8 @@ static int snd_emu10k1_free(struct snd_emu10k1 *emu)
                kthread_stop(emu->emu1010.firmware_thread);
        if (emu->firmware)
                release_firmware(emu->firmware);
+       if (emu->dock_fw)
+               release_firmware(emu->dock_fw);
        if (emu->irq >= 0)
                free_irq(emu->irq, emu);
        /* remove reserved page */