[ALSA] Remove sound/driver.h
[pandora-kernel.git] / sound / pci / emu10k1 / emu10k1_main.c
index 4a9b59a..69f342c 100644 (file)
@@ -1,5 +1,5 @@
 /*
- *  Copyright (c) by Jaroslav Kysela <perex@suse.cz>
+ *  Copyright (c) by Jaroslav Kysela <perex@perex.cz>
  *                   Creative Labs, Inc.
  *  Routines for control of EMU10K1 chips
  *
@@ -31,7 +31,8 @@
  *
  */
 
-#include <sound/driver.h>
+#include <linux/sched.h>
+#include <linux/kthread.h>
 #include <linux/delay.h>
 #include <linux/init.h>
 #include <linux/interrupt.h>
 
 #define HANA_FILENAME "emu/hana.fw"
 #define DOCK_FILENAME "emu/audio_dock.fw"
+#define EMU1010B_FILENAME "emu/emu1010b.fw"
+#define MICRO_DOCK_FILENAME "emu/micro_dock.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(EMU1010_NOTEBOOK_FILENAME);
 
 
 /*************************************************************************
@@ -660,10 +667,12 @@ 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
@@ -694,6 +703,96 @@ static int snd_emu1010_load_firmware(struct snd_emu10k1 * emu, const char * file
        return 0;
 }
 
+int emu1010_firmware_thread(void *data) {
+       struct snd_emu10k1 * emu = data;
+       int tmp,tmp2;
+       int reg;
+       int err;
+
+       for (;;) {
+               /* Delay to allow Audio Dock to settle */
+               msleep(1000);
+               if (kthread_should_stop())
+                       break;
+               snd_emu1010_fpga_read(emu, EMU_HANA_IRQ_STATUS, &tmp ); /* IRQ Status */
+               snd_emu1010_fpga_read(emu, EMU_HANA_OPTION_CARDS, &reg ); /* OPTIONS: Which cards are attached to the EMU */
+               if (reg & EMU_HANA_OPTION_DOCK_OFFLINE) {
+                       /* Audio Dock attached */
+                       /* 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 ((err = snd_emu1010_load_firmware(emu, DOCK_FILENAME)) != 0) {
+                                       return err;
+                               }
+                       } else if (emu->card_capabilities->emu1010 == 2) {
+                               if ((err = snd_emu1010_load_firmware(emu, MICRO_DOCK_FILENAME)) != 0) {
+                                       return err;
+                               }
+                       } else if (emu->card_capabilities->emu1010 == 3) {
+                               if ((err = snd_emu1010_load_firmware(emu, MICRO_DOCK_FILENAME)) != 0) {
+                                       return err;
+                               }
+                       }
+
+                       snd_emu1010_fpga_write(emu,  EMU_HANA_FPGA_CONFIG, 0 );
+                       snd_emu1010_fpga_read(emu, EMU_HANA_IRQ_STATUS, &reg );
+                       snd_printk(KERN_INFO "emu1010: EMU_HANA+DOCK_IRQ_STATUS=0x%x\n",reg);
+                       /* ID, should read & 0x7f = 0x55 when FPGA programmed. */
+                       snd_emu1010_fpga_read(emu, EMU_HANA_ID, &reg );
+                       snd_printk(KERN_INFO "emu1010: EMU_HANA+DOCK_ID=0x%x\n",reg);
+                       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;
+                       }
+                       snd_printk(KERN_INFO "emu1010: Audio Dock Firmware loaded\n");
+                       snd_emu1010_fpga_read(emu, EMU_DOCK_MAJOR_REV, &tmp );
+                       snd_emu1010_fpga_read(emu, EMU_DOCK_MINOR_REV, &tmp2 );
+                       snd_printk("Audio Dock ver:%d.%d\n",tmp ,tmp2);
+                       /* Sync clocking between 1010 and Dock */
+                       /* Allow DLL to settle */
+                       msleep(10);
+                       /* Unmute all. Default is muted after a firmware load */
+                       snd_emu1010_fpga_write(emu, EMU_HANA_UNMUTE, EMU_UNMUTE );
+                       break;
+               }
+       }
+       return 0;
+}
+
+/*
+ * EMU-1010 - details found out from this driver, official MS Win drivers,
+ * testing the card:
+ *
+ * Audigy2 (aka Alice2):
+ * ---------------------
+ *     * communication over PCI
+ *     * conversion of 32-bit data coming over EMU32 links from HANA FPGA
+ *       to 2 x 16-bit, using internal DSP instructions
+ *     * slave mode, clock supplied by HANA
+ *     * linked to HANA using:
+ *             32 x 32-bit serial EMU32 output channels
+ *             16 x EMU32 input channels
+ *             (?) x I2S I/O channels (?)
+ *
+ * FPGA (aka HANA):
+ * ---------------
+ *     * provides all (?) physical inputs and outputs of the card
+ *             (ADC, DAC, SPDIF I/O, ADAT I/O, etc.)
+ *     * provides clock signal for the card and Alice2
+ *     * two crystals - for 44.1kHz and 48kHz multiples
+ *     * provides internal routing of signal sources to signal destinations
+ *     * inputs/outputs to Alice2 - see above
+ *
+ * Current status of the driver:
+ * ----------------------------
+ *     * only 44.1/48kHz supported (the MS Win driver supports up to 192 kHz)
+ *     * PCM device nb. 2:
+ *             16 x 16-bit playback - snd_emu10k1_fx8010_playback_ops
+ *             16 x 32-bit capture - snd_emu10k1_capture_efx_ops
+ */
 static int snd_emu10k1_emu1010_init(struct snd_emu10k1 * emu)
 {
        unsigned int i;
@@ -727,7 +826,7 @@ static int snd_emu10k1_emu1010_init(struct snd_emu10k1 * emu)
        /* ID, should read & 0x7f = 0x55. (Bit 7 is the IRQ bit) */
        snd_emu1010_fpga_read(emu, EMU_HANA_ID, &reg );
        snd_printdd("reg1=0x%x\n",reg);
-       if (reg == 0x55) {
+       if ((reg & 0x3f) == 0x15) {
                /* FPGA netlist already present so clear it */
                /* Return to programming mode */
 
@@ -735,19 +834,32 @@ static int snd_emu10k1_emu1010_init(struct snd_emu10k1 * emu)
        }
        snd_emu1010_fpga_read(emu, EMU_HANA_ID, &reg );
        snd_printdd("reg2=0x%x\n",reg);
-       if (reg == 0x55) {
+       if ((reg & 0x3f) == 0x15) {
                /* FPGA failed to return to programming mode */
+               snd_printk(KERN_INFO "emu1010: FPGA failed to return to programming mode\n");
                return -ENODEV;
        }
        snd_printk(KERN_INFO "emu1010: EMU_HANA_ID=0x%x\n",reg);
-       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;
+       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;
+               }
        }
 
        /* ID, should read & 0x7f = 0x55 when FPGA programmed. */
        snd_emu1010_fpga_read(emu, EMU_HANA_ID, &reg );
-       if (reg != 0x55) {
+       if ((reg & 0x3f) != 0x15) {
                /* FPGA failed to be programmed */
                snd_printk(KERN_INFO "emu1010: Loading Hana Firmware file failed, reg=0x%x\n", reg);
                return -ENODEV;
@@ -765,8 +877,16 @@ static int snd_emu10k1_emu1010_init(struct snd_emu10k1 * emu)
        snd_emu1010_fpga_read(emu, EMU_HANA_OPTION_CARDS, &reg );
        snd_printk(KERN_INFO "emu1010: Card options=0x%x\n",reg);
        snd_emu1010_fpga_read(emu, EMU_HANA_OPTICAL_TYPE, &tmp ); 
-       /* ADAT input. */
-       snd_emu1010_fpga_write(emu, EMU_HANA_OPTICAL_TYPE, 0x01 );
+       /* Optical -> ADAT I/O  */
+       /* 0 : SPDIF
+        * 1 : ADAT
+        */
+       emu->emu1010.optical_in = 1; /* IN_ADAT */
+       emu->emu1010.optical_out = 1; /* IN_ADAT */
+       tmp = 0;
+       tmp = (emu->emu1010.optical_in ? EMU_HANA_OPTICAL_IN_ADAT : 0) |
+               (emu->emu1010.optical_out ? EMU_HANA_OPTICAL_OUT_ADAT : 0);
+       snd_emu1010_fpga_write(emu, EMU_HANA_OPTICAL_TYPE, tmp );
        snd_emu1010_fpga_read(emu, EMU_HANA_ADC_PADS, &tmp );
        /* Set no attenuation on Audio Dock pads. */
        snd_emu1010_fpga_write(emu, EMU_HANA_ADC_PADS, 0x00 );
@@ -850,6 +970,27 @@ static int snd_emu10k1_emu1010_init(struct snd_emu10k1 * emu)
                EMU_DST_ALICE2_EMU32_6, EMU_SRC_DOCK_ADC2_LEFT1);
        snd_emu1010_fpga_link_dst_src_write(emu,
                EMU_DST_ALICE2_EMU32_7, EMU_SRC_DOCK_ADC2_RIGHT1);
+       /* Pavel Hofman - setting defaults for 8 more capture channels
+        * Defaults only, users will set their own values anyways, let's
+        * just copy/paste.
+        */
+       
+       snd_emu1010_fpga_link_dst_src_write(emu,
+               EMU_DST_ALICE2_EMU32_8, EMU_SRC_DOCK_MIC_A1);
+       snd_emu1010_fpga_link_dst_src_write(emu,
+               EMU_DST_ALICE2_EMU32_9, EMU_SRC_DOCK_MIC_B1);
+       snd_emu1010_fpga_link_dst_src_write(emu,
+               EMU_DST_ALICE2_EMU32_A, EMU_SRC_HAMOA_ADC_LEFT2);
+       snd_emu1010_fpga_link_dst_src_write(emu,
+               EMU_DST_ALICE2_EMU32_B, EMU_SRC_HAMOA_ADC_LEFT2);
+       snd_emu1010_fpga_link_dst_src_write(emu,
+               EMU_DST_ALICE2_EMU32_C, EMU_SRC_DOCK_ADC1_LEFT1);
+       snd_emu1010_fpga_link_dst_src_write(emu,
+               EMU_DST_ALICE2_EMU32_D, EMU_SRC_DOCK_ADC1_RIGHT1);
+       snd_emu1010_fpga_link_dst_src_write(emu,
+               EMU_DST_ALICE2_EMU32_E, EMU_SRC_DOCK_ADC2_LEFT1);
+       snd_emu1010_fpga_link_dst_src_write(emu,
+               EMU_DST_ALICE2_EMU32_F, EMU_SRC_DOCK_ADC2_RIGHT1);
 #endif
 #if 0
        /* Original */
@@ -931,38 +1072,12 @@ static int snd_emu10k1_emu1010_init(struct snd_emu10k1 * emu)
        snd_emu1010_fpga_read(emu, EMU_HANA_SPDIF_MODE, &tmp ); 
        snd_emu1010_fpga_write(emu, EMU_HANA_SPDIF_MODE, 0x10 ); /* SPDIF Format spdif  (or 0x11 for aes/ebu) */
 
-       /* Delay to allow Audio Dock to settle */
-       msleep(100);
-       snd_emu1010_fpga_read(emu, EMU_HANA_IRQ_STATUS, &tmp ); /* IRQ Status */
-       snd_emu1010_fpga_read(emu, EMU_HANA_OPTION_CARDS, &reg ); /* OPTIONS: Which cards are attached to the EMU */
-       /* FIXME: The loading of this should be able to happen any time,
-        * as the user can plug/unplug it at any time
-        */
-       if (reg & (EMU_HANA_OPTION_DOCK_ONLINE | EMU_HANA_OPTION_DOCK_OFFLINE) ) {
-               /* Audio Dock attached */
-               /* 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 ((err = snd_emu1010_load_firmware(emu, DOCK_FILENAME)) != 0) {
-                       return err;
-               }
-               snd_emu1010_fpga_write(emu,  EMU_HANA_FPGA_CONFIG, 0 );
-               snd_emu1010_fpga_read(emu, EMU_HANA_IRQ_STATUS, &reg );
-               snd_printk(KERN_INFO "emu1010: EMU_HANA+DOCK_IRQ_STATUS=0x%x\n",reg);
-               /* ID, should read & 0x7f = 0x55 when FPGA programmed. */
-               snd_emu1010_fpga_read(emu, EMU_HANA_ID, &reg );
-               snd_printk(KERN_INFO "emu1010: EMU_HANA+DOCK_ID=0x%x\n",reg);
-               if (reg != 0x55) {
-                       /* 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;
-               }
-               snd_printk(KERN_INFO "emu1010: Audio Dock Firmware loaded\n");
-               snd_emu1010_fpga_read(emu, EMU_DOCK_MAJOR_REV, &tmp );
-               snd_emu1010_fpga_read(emu, EMU_DOCK_MINOR_REV, &tmp2 );
-               snd_printk("Audio Dock ver:%d.%d\n",tmp ,tmp2);
-       }
+       /* Start Micro/Audio Dock firmware loader thread */
+       emu->emu1010.firmware_thread = kthread_create(&emu1010_firmware_thread,
+                                   emu,
+                                   "emu1010_firmware");
+       wake_up_process(emu->emu1010.firmware_thread);
+
 #if 0
        snd_emu1010_fpga_link_dst_src_write(emu,
                EMU_DST_HAMOA_DAC_LEFT1, EMU_SRC_ALICE_EMU32B + 2); /* ALICE2 bus 0xa2 */
@@ -1048,7 +1163,7 @@ static int snd_emu10k1_emu1010_init(struct snd_emu10k1 * emu)
        emu->emu1010.output_source[23] = 28;
 
        /* TEMP: Select SPDIF in/out */
-       snd_emu1010_fpga_write(emu, EMU_HANA_OPTICAL_TYPE, 0x0); /* Output spdif */
+       //snd_emu1010_fpga_write(emu, EMU_HANA_OPTICAL_TYPE, 0x0); /* Output spdif */
 
        /* TEMP: Select 48kHz SPDIF out */
        snd_emu1010_fpga_write(emu, EMU_HANA_UNMUTE, 0x0); /* Mute all */
@@ -1089,6 +1204,7 @@ static int snd_emu10k1_free(struct snd_emu10k1 *emu)
        if (emu->card_capabilities->emu1010) {
                /* Disable 48Volt power to Audio Dock */
                snd_emu1010_fpga_write(emu,  EMU_HANA_DOCK_PWR,  0 );
+               kthread_stop(emu->emu1010.firmware_thread);
        }
        if (emu->memhdr)
                snd_util_memhdr_free(emu->memhdr);
@@ -1227,9 +1343,15 @@ static struct snd_emu_chip_details emu_chip_details[] = {
         .emu10k2_chip = 1,
         .ca0108_chip = 1,
         .ca_cardbus_chip = 1,
-        .spi_dac = 1,
-        .i2c_adc = 1,
-        .spk71 = 1} ,
+        .spk71 = 1 ,
+        .emu1010 = 3} ,
+       {.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} ,
        {.vendor = 0x1102, .device = 0x0008, 
         .driver = "Audigy2", .name = "Audigy 2 Value [Unknown]", 
         .id = "Audigy2",
@@ -1632,8 +1754,9 @@ int __devinit snd_emu10k1_create(struct snd_card *card,
                goto error;
        }
 
-       emu->page_ptr_table = (void **)vmalloc(emu->max_cache_pages * sizeof(void*));
-       emu->page_addr_table = (unsigned long*)vmalloc(emu->max_cache_pages * sizeof(unsigned long));
+       emu->page_ptr_table = vmalloc(emu->max_cache_pages * sizeof(void *));
+       emu->page_addr_table = vmalloc(emu->max_cache_pages *
+                                      sizeof(unsigned long));
        if (emu->page_ptr_table == NULL || emu->page_addr_table == NULL) {
                err = -ENOMEM;
                goto error;
@@ -1663,12 +1786,13 @@ int __devinit snd_emu10k1_create(struct snd_card *card,
        emu->fx8010.extout_mask = extout_mask;
        emu->enable_ir = enable_ir;
 
+       if (emu->card_capabilities->ca_cardbus_chip) {
+               if ((err = snd_emu10k1_cardbus_init(emu)) < 0)
+                       goto error;
+       }
        if (emu->card_capabilities->ecard) {
                if ((err = snd_emu10k1_ecard_init(emu)) < 0)
                        goto error;
-       } else if (emu->card_capabilities->ca_cardbus_chip) {
-               if ((err = snd_emu10k1_cardbus_init(emu)) < 0)
-                       goto error;
        } else if (emu->card_capabilities->emu1010) {
                if ((err = snd_emu10k1_emu1010_init(emu)) < 0) {
                        snd_emu10k1_free(emu);
@@ -1814,10 +1938,10 @@ void snd_emu10k1_suspend_regs(struct snd_emu10k1 *emu)
 
 void snd_emu10k1_resume_init(struct snd_emu10k1 *emu)
 {
+       if (emu->card_capabilities->ca_cardbus_chip)
+               snd_emu10k1_cardbus_init(emu);
        if (emu->card_capabilities->ecard)
                snd_emu10k1_ecard_init(emu);
-       else if (emu->card_capabilities->ca_cardbus_chip)
-               snd_emu10k1_cardbus_init(emu);
        else if (emu->card_capabilities->emu1010)
                snd_emu10k1_emu1010_init(emu);
        else