diff -dup alsa-driver-1.0.22.1__orig/alsa-kernel/pci/echoaudio/darla20_dsp.c alsa-driver-1.0.22.1/alsa-kernel/pci/echoaudio/darla20_dsp.c --- alsa-driver-1.0.22.1__orig/alsa-kernel/pci/echoaudio/darla20_dsp.c 2009-12-28 15:21:33.000000000 +0100 +++ alsa-driver-1.0.22.1/alsa-kernel/pci/echoaudio/darla20_dsp.c 2010-01-02 21:27:05.000000000 +0100 @@ -45,7 +45,7 @@ static int init_hw(struct echoaudio *chi chip->device_id = device_id; chip->subdevice_id = subdevice_id; chip->bad_board = TRUE; - chip->dsp_code_to_load = &card_fw[FW_DARLA20_DSP]; + chip->dsp_code_to_load = FW_DARLA20_DSP; chip->spdif_status = GD_SPDIF_STATUS_UNDEF; chip->clock_state = GD_CLOCK_UNDEF; /* Since this card has no ASIC, mark it as loaded so everything diff -dup alsa-driver-1.0.22.1__orig/alsa-kernel/pci/echoaudio/darla24_dsp.c alsa-driver-1.0.22.1/alsa-kernel/pci/echoaudio/darla24_dsp.c --- alsa-driver-1.0.22.1__orig/alsa-kernel/pci/echoaudio/darla24_dsp.c 2009-12-28 15:21:33.000000000 +0100 +++ alsa-driver-1.0.22.1/alsa-kernel/pci/echoaudio/darla24_dsp.c 2010-01-02 21:27:05.000000000 +0100 @@ -45,7 +45,7 @@ static int init_hw(struct echoaudio *chi chip->device_id = device_id; chip->subdevice_id = subdevice_id; chip->bad_board = TRUE; - chip->dsp_code_to_load = &card_fw[FW_DARLA24_DSP]; + chip->dsp_code_to_load = FW_DARLA24_DSP; /* Since this card has no ASIC, mark it as loaded so everything works OK */ chip->asic_loaded = TRUE; diff -dup alsa-driver-1.0.22.1__orig/alsa-kernel/pci/echoaudio/echo3g_dsp.c alsa-driver-1.0.22.1/alsa-kernel/pci/echoaudio/echo3g_dsp.c --- alsa-driver-1.0.22.1__orig/alsa-kernel/pci/echoaudio/echo3g_dsp.c 2009-12-28 15:21:33.000000000 +0100 +++ alsa-driver-1.0.22.1/alsa-kernel/pci/echoaudio/echo3g_dsp.c 2010-01-02 21:27:05.000000000 +0100 @@ -61,7 +61,7 @@ static int init_hw(struct echoaudio *chi chip->subdevice_id = subdevice_id; chip->bad_board = TRUE; chip->has_midi = TRUE; - chip->dsp_code_to_load = &card_fw[FW_ECHO3G_DSP]; + chip->dsp_code_to_load = FW_ECHO3G_DSP; /* Load the DSP code and the ASIC on the PCI card and get what type of external box is attached */ diff -dup alsa-driver-1.0.22.1__orig/alsa-kernel/pci/echoaudio/echoaudio_3g.c alsa-driver-1.0.22.1/alsa-kernel/pci/echoaudio/echoaudio_3g.c --- alsa-driver-1.0.22.1__orig/alsa-kernel/pci/echoaudio/echoaudio_3g.c 2009-12-28 15:21:33.000000000 +0100 +++ alsa-driver-1.0.22.1/alsa-kernel/pci/echoaudio/echoaudio_3g.c 2010-01-02 21:27:05.000000000 +0100 @@ -227,12 +227,11 @@ static int load_asic(struct echoaudio *c /* Give the DSP a few milliseconds to settle down */ mdelay(2); - err = load_asic_generic(chip, DSP_FNC_LOAD_3G_ASIC, - &card_fw[FW_3G_ASIC]); + err = load_asic_generic(chip, DSP_FNC_LOAD_3G_ASIC, FW_3G_ASIC); if (err < 0) return err; - chip->asic_code = &card_fw[FW_3G_ASIC]; + chip->asic_code = FW_3G_ASIC; /* Now give the new ASIC some time to set up */ msleep(1000); diff -dup alsa-driver-1.0.22.1__orig/alsa-kernel/pci/echoaudio/echoaudio.c alsa-driver-1.0.22.1/alsa-kernel/pci/echoaudio/echoaudio.c --- alsa-driver-1.0.22.1__orig/alsa-kernel/pci/echoaudio/echoaudio.c 2009-12-28 15:21:33.000000000 +0100 +++ alsa-driver-1.0.22.1/alsa-kernel/pci/echoaudio/echoaudio.c 2010-01-02 21:27:05.000000000 +0100 @@ -36,11 +36,15 @@ MODULE_PARM_DESC(enable, "Enable " ECHOC static unsigned int channels_list[10] = {1, 2, 4, 6, 8, 10, 12, 14, 16, 999999}; static const DECLARE_TLV_DB_SCALE(db_scale_output_gain, -12800, 100, 1); + + static int get_firmware(const struct firmware **fw_entry, - const struct firmware *frm, struct echoaudio *chip) + struct echoaudio *chip, const short fw_index) { int err; char name[30]; + const struct firmware *frm = &card_fw[fw_index]; + DE_ACT(("firmware requested: %s\n", frm->data)); snprintf(name, sizeof(name), "ea/%s", frm->data); if ((err = request_firmware(fw_entry, name, pci_device(chip))) < 0) @@ -48,6 +52,8 @@ static int get_firmware(const struct fir return err; } + + static void free_firmware(const struct firmware *fw_entry) { release_firmware(fw_entry); diff -dup alsa-driver-1.0.22.1__orig/alsa-kernel/pci/echoaudio/echoaudio_dsp.c alsa-driver-1.0.22.1/alsa-kernel/pci/echoaudio/echoaudio_dsp.c --- alsa-driver-1.0.22.1__orig/alsa-kernel/pci/echoaudio/echoaudio_dsp.c 2009-12-28 15:21:33.000000000 +0100 +++ alsa-driver-1.0.22.1/alsa-kernel/pci/echoaudio/echoaudio_dsp.c 2010-01-02 21:27:05.000000000 +0100 @@ -175,15 +175,15 @@ static inline int check_asic_status(stru #ifdef ECHOCARD_HAS_ASIC /* Load ASIC code - done after the DSP is loaded */ -static int load_asic_generic(struct echoaudio *chip, u32 cmd, - const struct firmware *asic) +static int load_asic_generic(struct echoaudio *chip, u32 cmd, short asic) { const struct firmware *fw; int err; u32 i, size; u8 *code; - if ((err = get_firmware(&fw, asic, chip)) < 0) { + err = get_firmware(&fw, chip, asic); + if (err < 0) { snd_printk(KERN_WARNING "Firmware not found !\n"); return err; } @@ -245,7 +245,8 @@ static int install_resident_loader(struc return 0; } - if ((i = get_firmware(&fw, &card_fw[FW_361_LOADER], chip)) < 0) { + i = get_firmware(&fw, chip, FW_361_LOADER); + if (i < 0) { snd_printk(KERN_WARNING "Firmware not found !\n"); return i; } @@ -485,7 +486,8 @@ static int load_firmware(struct echoaudi chip->dsp_code = NULL; } - if ((err = get_firmware(&fw, chip->dsp_code_to_load, chip)) < 0) + err = get_firmware(&fw, chip, chip->dsp_code_to_load); + if (err < 0) return err; err = load_dsp(chip, (u16 *)fw->data); free_firmware(fw); diff -dup alsa-driver-1.0.22.1__orig/alsa-kernel/pci/echoaudio/echoaudio.h alsa-driver-1.0.22.1/alsa-kernel/pci/echoaudio/echoaudio.h --- alsa-driver-1.0.22.1__orig/alsa-kernel/pci/echoaudio/echoaudio.h 2009-12-28 15:21:33.000000000 +0100 +++ alsa-driver-1.0.22.1/alsa-kernel/pci/echoaudio/echoaudio.h 2010-01-02 21:27:05.000000000 +0100 @@ -442,8 +442,8 @@ struct echoaudio { u16 device_id, subdevice_id; u16 *dsp_code; /* Current DSP code loaded, * NULL if nothing loaded */ - const struct firmware *dsp_code_to_load;/* DSP code to load */ - const struct firmware *asic_code; /* Current ASIC code */ + short dsp_code_to_load; /* DSP code to load */ + short asic_code; /* Current ASIC code */ u32 comm_page_phys; /* Physical address of the * memory seen by DSP */ volatile u32 __iomem *dsp_registers; /* DSP's register base */ @@ -464,7 +464,7 @@ static int load_firmware(struct echoaudi static int wait_handshake(struct echoaudio *chip); static int send_vector(struct echoaudio *chip, u32 command); static int get_firmware(const struct firmware **fw_entry, - const struct firmware *frm, struct echoaudio *chip); + struct echoaudio *chip, const short fw_index); static void free_firmware(const struct firmware *fw_entry); #ifdef ECHOCARD_HAS_MIDI diff -dup alsa-driver-1.0.22.1__orig/alsa-kernel/pci/echoaudio/gina20_dsp.c alsa-driver-1.0.22.1/alsa-kernel/pci/echoaudio/gina20_dsp.c --- alsa-driver-1.0.22.1__orig/alsa-kernel/pci/echoaudio/gina20_dsp.c 2009-12-28 15:21:33.000000000 +0100 +++ alsa-driver-1.0.22.1/alsa-kernel/pci/echoaudio/gina20_dsp.c 2010-01-02 21:27:05.000000000 +0100 @@ -49,7 +49,7 @@ static int init_hw(struct echoaudio *chi chip->device_id = device_id; chip->subdevice_id = subdevice_id; chip->bad_board = TRUE; - chip->dsp_code_to_load = &card_fw[FW_GINA20_DSP]; + chip->dsp_code_to_load = FW_GINA20_DSP; chip->spdif_status = GD_SPDIF_STATUS_UNDEF; chip->clock_state = GD_CLOCK_UNDEF; /* Since this card has no ASIC, mark it as loaded so everything diff -dup alsa-driver-1.0.22.1__orig/alsa-kernel/pci/echoaudio/gina24_dsp.c alsa-driver-1.0.22.1/alsa-kernel/pci/echoaudio/gina24_dsp.c --- alsa-driver-1.0.22.1__orig/alsa-kernel/pci/echoaudio/gina24_dsp.c 2009-12-28 15:21:33.000000000 +0100 +++ alsa-driver-1.0.22.1/alsa-kernel/pci/echoaudio/gina24_dsp.c 2010-01-02 21:27:05.000000000 +0100 @@ -33,8 +33,7 @@ static int write_control_reg(struct echo static int set_input_clock(struct echoaudio *chip, u16 clock); static int set_professional_spdif(struct echoaudio *chip, char prof); static int set_digital_mode(struct echoaudio *chip, u8 mode); -static int load_asic_generic(struct echoaudio *chip, u32 cmd, - const struct firmware *asic); +static int load_asic_generic(struct echoaudio *chip, u32 cmd, short asic); static int check_asic_status(struct echoaudio *chip); @@ -64,13 +63,13 @@ static int init_hw(struct echoaudio *chi /* Gina24 comes in both '301 and '361 flavors */ if (chip->device_id == DEVICE_ID_56361) { - chip->dsp_code_to_load = &card_fw[FW_GINA24_361_DSP]; + chip->dsp_code_to_load = FW_GINA24_361_DSP; chip->digital_modes = ECHOCAPS_HAS_DIGITAL_MODE_SPDIF_RCA | ECHOCAPS_HAS_DIGITAL_MODE_SPDIF_OPTICAL | ECHOCAPS_HAS_DIGITAL_MODE_ADAT; } else { - chip->dsp_code_to_load = &card_fw[FW_GINA24_301_DSP]; + chip->dsp_code_to_load = FW_GINA24_301_DSP; chip->digital_modes = ECHOCAPS_HAS_DIGITAL_MODE_SPDIF_RCA | ECHOCAPS_HAS_DIGITAL_MODE_SPDIF_OPTICAL | @@ -125,7 +124,7 @@ static int load_asic(struct echoaudio *c { u32 control_reg; int err; - const struct firmware *fw; + short asic; if (chip->asic_loaded) return 1; @@ -135,14 +134,15 @@ static int load_asic(struct echoaudio *c /* Pick the correct ASIC for '301 or '361 Gina24 */ if (chip->device_id == DEVICE_ID_56361) - fw = &card_fw[FW_GINA24_361_ASIC]; + asic = FW_GINA24_361_ASIC; else - fw = &card_fw[FW_GINA24_301_ASIC]; + asic = FW_GINA24_301_ASIC; - if ((err = load_asic_generic(chip, DSP_FNC_LOAD_GINA24_ASIC, fw)) < 0) + err = load_asic_generic(chip, DSP_FNC_LOAD_GINA24_ASIC, asic); + if (err < 0) return err; - chip->asic_code = fw; + chip->asic_code = asic; /* Now give the new ASIC a little time to set up */ mdelay(10); diff -dup alsa-driver-1.0.22.1__orig/alsa-kernel/pci/echoaudio/indigodj_dsp.c alsa-driver-1.0.22.1/alsa-kernel/pci/echoaudio/indigodj_dsp.c --- alsa-driver-1.0.22.1__orig/alsa-kernel/pci/echoaudio/indigodj_dsp.c 2009-12-28 15:21:33.000000000 +0100 +++ alsa-driver-1.0.22.1/alsa-kernel/pci/echoaudio/indigodj_dsp.c 2010-01-02 21:27:05.000000000 +0100 @@ -50,7 +50,7 @@ static int init_hw(struct echoaudio *chi chip->device_id = device_id; chip->subdevice_id = subdevice_id; chip->bad_board = TRUE; - chip->dsp_code_to_load = &card_fw[FW_INDIGO_DJ_DSP]; + chip->dsp_code_to_load = FW_INDIGO_DJ_DSP; /* Since this card has no ASIC, mark it as loaded so everything works OK */ chip->asic_loaded = TRUE; diff -dup alsa-driver-1.0.22.1__orig/alsa-kernel/pci/echoaudio/indigodjx_dsp.c alsa-driver-1.0.22.1/alsa-kernel/pci/echoaudio/indigodjx_dsp.c --- alsa-driver-1.0.22.1__orig/alsa-kernel/pci/echoaudio/indigodjx_dsp.c 2009-12-28 15:21:33.000000000 +0100 +++ alsa-driver-1.0.22.1/alsa-kernel/pci/echoaudio/indigodjx_dsp.c 2010-01-02 21:27:05.000000000 +0100 @@ -48,7 +48,7 @@ static int init_hw(struct echoaudio *chi chip->device_id = device_id; chip->subdevice_id = subdevice_id; chip->bad_board = TRUE; - chip->dsp_code_to_load = &card_fw[FW_INDIGO_DJX_DSP]; + chip->dsp_code_to_load = FW_INDIGO_DJX_DSP; /* Since this card has no ASIC, mark it as loaded so everything works OK */ chip->asic_loaded = TRUE; diff -dup alsa-driver-1.0.22.1__orig/alsa-kernel/pci/echoaudio/indigo_dsp.c alsa-driver-1.0.22.1/alsa-kernel/pci/echoaudio/indigo_dsp.c --- alsa-driver-1.0.22.1__orig/alsa-kernel/pci/echoaudio/indigo_dsp.c 2009-12-28 15:21:33.000000000 +0100 +++ alsa-driver-1.0.22.1/alsa-kernel/pci/echoaudio/indigo_dsp.c 2010-01-02 21:27:05.000000000 +0100 @@ -50,7 +50,7 @@ static int init_hw(struct echoaudio *chi chip->device_id = device_id; chip->subdevice_id = subdevice_id; chip->bad_board = TRUE; - chip->dsp_code_to_load = &card_fw[FW_INDIGO_DSP]; + chip->dsp_code_to_load = FW_INDIGO_DSP; /* Since this card has no ASIC, mark it as loaded so everything works OK */ chip->asic_loaded = TRUE; diff -dup alsa-driver-1.0.22.1__orig/alsa-kernel/pci/echoaudio/indigoio_dsp.c alsa-driver-1.0.22.1/alsa-kernel/pci/echoaudio/indigoio_dsp.c --- alsa-driver-1.0.22.1__orig/alsa-kernel/pci/echoaudio/indigoio_dsp.c 2009-12-28 15:21:33.000000000 +0100 +++ alsa-driver-1.0.22.1/alsa-kernel/pci/echoaudio/indigoio_dsp.c 2010-01-02 21:27:05.000000000 +0100 @@ -50,7 +50,7 @@ static int init_hw(struct echoaudio *chi chip->device_id = device_id; chip->subdevice_id = subdevice_id; chip->bad_board = TRUE; - chip->dsp_code_to_load = &card_fw[FW_INDIGO_IO_DSP]; + chip->dsp_code_to_load = FW_INDIGO_IO_DSP; /* Since this card has no ASIC, mark it as loaded so everything works OK */ chip->asic_loaded = TRUE; diff -dup alsa-driver-1.0.22.1__orig/alsa-kernel/pci/echoaudio/indigoiox_dsp.c alsa-driver-1.0.22.1/alsa-kernel/pci/echoaudio/indigoiox_dsp.c --- alsa-driver-1.0.22.1__orig/alsa-kernel/pci/echoaudio/indigoiox_dsp.c 2009-12-28 15:21:33.000000000 +0100 +++ alsa-driver-1.0.22.1/alsa-kernel/pci/echoaudio/indigoiox_dsp.c 2010-01-02 21:27:05.000000000 +0100 @@ -48,7 +48,7 @@ static int init_hw(struct echoaudio *chi chip->device_id = device_id; chip->subdevice_id = subdevice_id; chip->bad_board = TRUE; - chip->dsp_code_to_load = &card_fw[FW_INDIGO_IOX_DSP]; + chip->dsp_code_to_load = FW_INDIGO_IOX_DSP; /* Since this card has no ASIC, mark it as loaded so everything works OK */ chip->asic_loaded = TRUE; diff -dup alsa-driver-1.0.22.1__orig/alsa-kernel/pci/echoaudio/layla20_dsp.c alsa-driver-1.0.22.1/alsa-kernel/pci/echoaudio/layla20_dsp.c --- alsa-driver-1.0.22.1__orig/alsa-kernel/pci/echoaudio/layla20_dsp.c 2009-12-28 15:21:33.000000000 +0100 +++ alsa-driver-1.0.22.1/alsa-kernel/pci/echoaudio/layla20_dsp.c 2010-01-02 21:27:05.000000000 +0100 @@ -31,8 +31,7 @@ static int read_dsp(struct echoaudio *chip, u32 *data); static int set_professional_spdif(struct echoaudio *chip, char prof); -static int load_asic_generic(struct echoaudio *chip, u32 cmd, - const struct firmware *asic); +static int load_asic_generic(struct echoaudio *chip, u32 cmd, short asic); static int check_asic_status(struct echoaudio *chip); static int update_flags(struct echoaudio *chip); @@ -54,7 +53,7 @@ static int init_hw(struct echoaudio *chi chip->subdevice_id = subdevice_id; chip->bad_board = TRUE; chip->has_midi = TRUE; - chip->dsp_code_to_load = &card_fw[FW_LAYLA20_DSP]; + chip->dsp_code_to_load = FW_LAYLA20_DSP; chip->input_clock_types = ECHO_CLOCK_BIT_INTERNAL | ECHO_CLOCK_BIT_SPDIF | ECHO_CLOCK_BIT_WORD | ECHO_CLOCK_BIT_SUPER; @@ -144,7 +143,7 @@ static int load_asic(struct echoaudio *c return 0; err = load_asic_generic(chip, DSP_FNC_LOAD_LAYLA_ASIC, - &card_fw[FW_LAYLA20_ASIC]); + FW_LAYLA20_ASIC); if (err < 0) return err; diff -dup alsa-driver-1.0.22.1__orig/alsa-kernel/pci/echoaudio/layla24_dsp.c alsa-driver-1.0.22.1/alsa-kernel/pci/echoaudio/layla24_dsp.c --- alsa-driver-1.0.22.1__orig/alsa-kernel/pci/echoaudio/layla24_dsp.c 2009-12-28 15:21:33.000000000 +0100 +++ alsa-driver-1.0.22.1/alsa-kernel/pci/echoaudio/layla24_dsp.c 2010-01-02 21:27:05.000000000 +0100 @@ -32,8 +32,7 @@ static int write_control_reg(struct echo static int set_input_clock(struct echoaudio *chip, u16 clock); static int set_professional_spdif(struct echoaudio *chip, char prof); static int set_digital_mode(struct echoaudio *chip, u8 mode); -static int load_asic_generic(struct echoaudio *chip, u32 cmd, - const struct firmware *asic); +static int load_asic_generic(struct echoaudio *chip, u32 cmd, short asic); static int check_asic_status(struct echoaudio *chip); @@ -54,7 +53,7 @@ static int init_hw(struct echoaudio *chi chip->subdevice_id = subdevice_id; chip->bad_board = TRUE; chip->has_midi = TRUE; - chip->dsp_code_to_load = &card_fw[FW_LAYLA24_DSP]; + chip->dsp_code_to_load = FW_LAYLA24_DSP; chip->input_clock_types = ECHO_CLOCK_BIT_INTERNAL | ECHO_CLOCK_BIT_SPDIF | ECHO_CLOCK_BIT_WORD | ECHO_CLOCK_BIT_ADAT; @@ -123,18 +122,18 @@ static int load_asic(struct echoaudio *c /* Load the ASIC for the PCI card */ err = load_asic_generic(chip, DSP_FNC_LOAD_LAYLA24_PCI_CARD_ASIC, - &card_fw[FW_LAYLA24_1_ASIC]); + FW_LAYLA24_1_ASIC); if (err < 0) return err; - chip->asic_code = &card_fw[FW_LAYLA24_2S_ASIC]; + chip->asic_code = FW_LAYLA24_2S_ASIC; /* Now give the new ASIC a little time to set up */ mdelay(10); /* Do the external one */ err = load_asic_generic(chip, DSP_FNC_LOAD_LAYLA24_EXTERNAL_ASIC, - &card_fw[FW_LAYLA24_2S_ASIC]); + FW_LAYLA24_2S_ASIC); if (err < 0) return FALSE; @@ -299,7 +298,7 @@ static int set_input_clock(struct echoau /* Depending on what digital mode you want, Layla24 needs different ASICs loaded. This function checks the ASIC needed for the new mode and sees if it matches the one already loaded. */ -static int switch_asic(struct echoaudio *chip, const struct firmware *asic) +static int switch_asic(struct echoaudio *chip, short asic) { s8 *monitors; @@ -335,7 +334,7 @@ static int dsp_set_digital_mode(struct e { u32 control_reg; int err, incompatible_clock; - const struct firmware *asic; + short asic; /* Set clock to "internal" if it's not compatible with the new mode */ incompatible_clock = FALSE; @@ -344,12 +343,12 @@ static int dsp_set_digital_mode(struct e case DIGITAL_MODE_SPDIF_RCA: if (chip->input_clock == ECHO_CLOCK_ADAT) incompatible_clock = TRUE; - asic = &card_fw[FW_LAYLA24_2S_ASIC]; + asic = FW_LAYLA24_2S_ASIC; break; case DIGITAL_MODE_ADAT: if (chip->input_clock == ECHO_CLOCK_SPDIF) incompatible_clock = TRUE; - asic = &card_fw[FW_LAYLA24_2A_ASIC]; + asic = FW_LAYLA24_2A_ASIC; break; default: DE_ACT(("Digital mode not supported: %d\n", mode)); diff -dup alsa-driver-1.0.22.1__orig/alsa-kernel/pci/echoaudio/mia_dsp.c alsa-driver-1.0.22.1/alsa-kernel/pci/echoaudio/mia_dsp.c --- alsa-driver-1.0.22.1__orig/alsa-kernel/pci/echoaudio/mia_dsp.c 2009-12-28 15:21:33.000000000 +0100 +++ alsa-driver-1.0.22.1/alsa-kernel/pci/echoaudio/mia_dsp.c 2010-01-02 21:27:05.000000000 +0100 @@ -53,7 +53,7 @@ static int init_hw(struct echoaudio *chi chip->device_id = device_id; chip->subdevice_id = subdevice_id; chip->bad_board = TRUE; - chip->dsp_code_to_load = &card_fw[FW_MIA_DSP]; + chip->dsp_code_to_load = FW_MIA_DSP; /* Since this card has no ASIC, mark it as loaded so everything works OK */ chip->asic_loaded = TRUE; diff -dup alsa-driver-1.0.22.1__orig/alsa-kernel/pci/echoaudio/mona_dsp.c alsa-driver-1.0.22.1/alsa-kernel/pci/echoaudio/mona_dsp.c --- alsa-driver-1.0.22.1__orig/alsa-kernel/pci/echoaudio/mona_dsp.c 2009-12-28 15:21:33.000000000 +0100 +++ alsa-driver-1.0.22.1/alsa-kernel/pci/echoaudio/mona_dsp.c 2010-01-02 21:27:05.000000000 +0100 @@ -33,8 +33,7 @@ static int write_control_reg(struct echo static int set_input_clock(struct echoaudio *chip, u16 clock); static int set_professional_spdif(struct echoaudio *chip, char prof); static int set_digital_mode(struct echoaudio *chip, u8 mode); -static int load_asic_generic(struct echoaudio *chip, u32 cmd, - const struct firmware *asic); +static int load_asic_generic(struct echoaudio *chip, u32 cmd, short asic); static int check_asic_status(struct echoaudio *chip); @@ -64,9 +63,9 @@ static int init_hw(struct echoaudio *chi /* Mona comes in both '301 and '361 flavors */ if (chip->device_id == DEVICE_ID_56361) - chip->dsp_code_to_load = &card_fw[FW_MONA_361_DSP]; + chip->dsp_code_to_load = FW_MONA_361_DSP; else - chip->dsp_code_to_load = &card_fw[FW_MONA_301_DSP]; + chip->dsp_code_to_load = FW_MONA_301_DSP; chip->digital_mode = DIGITAL_MODE_SPDIF_RCA; chip->professional_spdif = FALSE; @@ -120,7 +119,7 @@ static int load_asic(struct echoaudio *c { u32 control_reg; int err; - const struct firmware *asic; + short asic; if (chip->asic_loaded) return 0; @@ -128,9 +127,9 @@ static int load_asic(struct echoaudio *c mdelay(10); if (chip->device_id == DEVICE_ID_56361) - asic = &card_fw[FW_MONA_361_1_ASIC48]; + asic = FW_MONA_361_1_ASIC48; else - asic = &card_fw[FW_MONA_301_1_ASIC48]; + asic = FW_MONA_301_1_ASIC48; err = load_asic_generic(chip, DSP_FNC_LOAD_MONA_PCI_CARD_ASIC, asic); if (err < 0) @@ -141,7 +140,7 @@ static int load_asic(struct echoaudio *c /* Do the external one */ err = load_asic_generic(chip, DSP_FNC_LOAD_MONA_EXTERNAL_ASIC, - &card_fw[FW_MONA_2_ASIC]); + FW_MONA_2_ASIC); if (err < 0) return err; @@ -165,22 +164,22 @@ loaded. This function checks the ASIC n if it matches the one already loaded. */ static int switch_asic(struct echoaudio *chip, char double_speed) { - const struct firmware *asic; int err; + short asic; /* Check the clock detect bits to see if this is a single-speed clock or a double-speed clock; load a new ASIC if necessary. */ if (chip->device_id == DEVICE_ID_56361) { if (double_speed) - asic = &card_fw[FW_MONA_361_1_ASIC96]; + asic = FW_MONA_361_1_ASIC96; else - asic = &card_fw[FW_MONA_361_1_ASIC48]; + asic = FW_MONA_361_1_ASIC48; } else { if (double_speed) - asic = &card_fw[FW_MONA_301_1_ASIC96]; + asic = FW_MONA_301_1_ASIC96; else - asic = &card_fw[FW_MONA_301_1_ASIC48]; + asic = FW_MONA_301_1_ASIC48; } if (asic != chip->asic_code) { @@ -200,7 +199,7 @@ static int switch_asic(struct echoaudio static int set_sample_rate(struct echoaudio *chip, u32 rate) { u32 control_reg, clock; - const struct firmware *asic; + short asic; char force_write; /* Only set the clock for internal mode. */ @@ -218,14 +217,14 @@ static int set_sample_rate(struct echoau if (chip->digital_mode == DIGITAL_MODE_ADAT) return -EINVAL; if (chip->device_id == DEVICE_ID_56361) - asic = &card_fw[FW_MONA_361_1_ASIC96]; + asic = FW_MONA_361_1_ASIC96; else - asic = &card_fw[FW_MONA_301_1_ASIC96]; + asic = FW_MONA_301_1_ASIC96; } else { if (chip->device_id == DEVICE_ID_56361) - asic = &card_fw[FW_MONA_361_1_ASIC48]; + asic = FW_MONA_361_1_ASIC48; else - asic = &card_fw[FW_MONA_301_1_ASIC48]; + asic = FW_MONA_301_1_ASIC48; } force_write = 0; @@ -410,8 +409,8 @@ static int dsp_set_digital_mode(struct e case DIGITAL_MODE_ADAT: /* If the current ASIC is the 96KHz ASIC, switch the ASIC and set to 48 KHz */ - if (chip->asic_code == &card_fw[FW_MONA_361_1_ASIC96] || - chip->asic_code == &card_fw[FW_MONA_301_1_ASIC96]) { + if (chip->asic_code == FW_MONA_361_1_ASIC96 || + chip->asic_code == FW_MONA_301_1_ASIC96) { set_sample_rate(chip, 48000); } control_reg |= GML_ADAT_MODE; diff -dup alsa-driver-1.0.22.1__orig/alsa-kernel/pci/echoaudio/echoaudio.c alsa-driver-1.0.22.1/alsa-kernel/pci/echoaudio/echoaudio.c --- alsa-driver-1.0.22.1__orig/alsa-kernel/pci/echoaudio/echoaudio.c 2010-01-02 21:27:05.000000000 +0100 +++ alsa-driver-1.0.22.1/alsa-kernel/pci/echoaudio/echoaudio.c 2010-01-02 21:28:08.000000000 +0100 @@ -43,12 +43,22 @@ static int get_firmware(const struct fir { int err; char name[30]; - const struct firmware *frm = &card_fw[fw_index]; - DE_ACT(("firmware requested: %s\n", frm->data)); - snprintf(name, sizeof(name), "ea/%s", frm->data); - if ((err = request_firmware(fw_entry, name, pci_device(chip))) < 0) + if (chip->fw_cache[fw_index]) { + DE_ACT(("firmware requested: %s is cached\n", card_fw[fw_index].data)); + *fw_entry = chip->fw_cache[fw_index]; + return 0; + } + + DE_ACT(("firmware requested: %s\n", card_fw[fw_index].data)); + snprintf(name, sizeof(name), "ea/%s", card_fw[fw_index].data); + err = request_firmware(fw_entry, name, pci_device(chip)); + if (err < 0) snd_printk(KERN_ERR "get_firmware(): Firmware not available (%d)\n", err); +#ifdef CONFIG_PM + else + chip->fw_cache[fw_index] = *fw_entry; +#endif return err; } @@ -56,8 +66,29 @@ static int get_firmware(const struct fir static void free_firmware(const struct firmware *fw_entry) { +#ifdef CONFIG_PM + DE_ACT(("firmware not released (kept in cache)\n")); +#else release_firmware(fw_entry); DE_ACT(("firmware released\n")); +#endif +} + + + +static void free_firmware_cache(struct echoaudio *chip) +{ +#ifdef CONFIG_PM + int i; + + for (i = 0; i < 8 ; i++) + if (chip->fw_cache[i]) { + release_firmware(chip->fw_cache[i]); + DE_ACT(("release_firmware(%d)\n", i)); + } + + DE_ACT(("firmware_cache released\n")); +#endif } @@ -1880,6 +1911,7 @@ static int snd_echo_free(struct echoaudi pci_disable_device(chip->pci); /* release chip data */ + free_firmware_cache(chip); kfree(chip); DE_INIT(("Chip freed.\n")); return 0; diff -dup alsa-driver-1.0.22.1__orig/alsa-kernel/pci/echoaudio/echoaudio.h alsa-driver-1.0.22.1/alsa-kernel/pci/echoaudio/echoaudio.h --- alsa-driver-1.0.22.1__orig/alsa-kernel/pci/echoaudio/echoaudio.h 2010-01-02 21:27:05.000000000 +0100 +++ alsa-driver-1.0.22.1/alsa-kernel/pci/echoaudio/echoaudio.h 2010-01-02 21:28:08.000000000 +0100 @@ -449,6 +449,9 @@ struct echoaudio { volatile u32 __iomem *dsp_registers; /* DSP's register base */ u32 active_mask; /* Chs. active mask or * punks out */ +#ifdef CONFIG_PM + const struct firmware *fw_cache[8]; /* Cached firmwares */ +#endif #ifdef ECHOCARD_HAS_MIDI u16 mtc_state; /* State for MIDI input parsing state machine */ diff -dup alsa-driver-1.0.22.1__orig/alsa-kernel/pci/echoaudio/darla20_dsp.c alsa-driver-1.0.22.1/alsa-kernel/pci/echoaudio/darla20_dsp.c --- alsa-driver-1.0.22.1__orig/alsa-kernel/pci/echoaudio/darla20_dsp.c 2010-01-07 21:43:00.000000000 +0100 +++ alsa-driver-1.0.22.1/alsa-kernel/pci/echoaudio/darla20_dsp.c 2010-01-01 22:15:54.000000000 +0100 @@ -57,15 +57,19 @@ static int init_hw(struct echoaudio *chi return err; chip->bad_board = FALSE; - if ((err = init_line_levels(chip)) < 0) - return err; - DE_INIT(("init_hw done\n")); return err; } +static int set_mixer_defaults(struct echoaudio *chip) +{ + return init_line_levels(chip); +} + + + /* The Darla20 has no external clock sources */ static u32 detect_input_clocks(const struct echoaudio *chip) { diff -dup alsa-driver-1.0.22.1__orig/alsa-kernel/pci/echoaudio/darla24_dsp.c alsa-driver-1.0.22.1/alsa-kernel/pci/echoaudio/darla24_dsp.c --- alsa-driver-1.0.22.1__orig/alsa-kernel/pci/echoaudio/darla24_dsp.c 2010-01-07 21:43:00.000000000 +0100 +++ alsa-driver-1.0.22.1/alsa-kernel/pci/echoaudio/darla24_dsp.c 2010-01-01 22:15:54.000000000 +0100 @@ -56,15 +56,19 @@ static int init_hw(struct echoaudio *chi return err; chip->bad_board = FALSE; - if ((err = init_line_levels(chip)) < 0) - return err; - DE_INIT(("init_hw done\n")); return err; } +static int set_mixer_defaults(struct echoaudio *chip) +{ + return init_line_levels(chip); +} + + + static u32 detect_input_clocks(const struct echoaudio *chip) { u32 clocks_from_dsp, clock_bits; diff -dup alsa-driver-1.0.22.1__orig/alsa-kernel/pci/echoaudio/echo3g_dsp.c alsa-driver-1.0.22.1/alsa-kernel/pci/echoaudio/echo3g_dsp.c --- alsa-driver-1.0.22.1__orig/alsa-kernel/pci/echoaudio/echo3g_dsp.c 2010-01-07 21:43:00.000000000 +0100 +++ alsa-driver-1.0.22.1/alsa-kernel/pci/echoaudio/echo3g_dsp.c 2010-01-01 22:15:54.000000000 +0100 @@ -97,20 +97,6 @@ static int init_hw(struct echoaudio *chi chip->digital_modes = ECHOCAPS_HAS_DIGITAL_MODE_SPDIF_RCA | ECHOCAPS_HAS_DIGITAL_MODE_SPDIF_OPTICAL | ECHOCAPS_HAS_DIGITAL_MODE_ADAT; - chip->digital_mode = DIGITAL_MODE_SPDIF_RCA; - chip->professional_spdif = FALSE; - chip->non_audio_spdif = FALSE; - chip->bad_board = FALSE; - - if ((err = init_line_levels(chip)) < 0) - return err; - err = set_digital_mode(chip, DIGITAL_MODE_SPDIF_RCA); - if (err < 0) - return err; - err = set_phantom_power(chip, 0); - if (err < 0) - return err; - err = set_professional_spdif(chip, TRUE); DE_INIT(("init_hw done\n")); return err; @@ -118,6 +104,18 @@ static int init_hw(struct echoaudio *chi +static int set_mixer_defaults(struct echoaudio *chip) +{ + chip->digital_mode = DIGITAL_MODE_SPDIF_RCA; + chip->professional_spdif = FALSE; + chip->non_audio_spdif = FALSE; + chip->bad_board = FALSE; + chip->phantom_power = FALSE; + return init_line_levels(chip); +} + + + static int set_phantom_power(struct echoaudio *chip, char on) { u32 control_reg = le32_to_cpu(chip->comm_page->control_register); diff -dup alsa-driver-1.0.22.1__orig/alsa-kernel/pci/echoaudio/echoaudio.c alsa-driver-1.0.22.1/alsa-kernel/pci/echoaudio/echoaudio.c --- alsa-driver-1.0.22.1__orig/alsa-kernel/pci/echoaudio/echoaudio.c 2010-01-07 21:43:03.000000000 +0100 +++ alsa-driver-1.0.22.1/alsa-kernel/pci/echoaudio/echoaudio.c 2010-01-07 21:48:51.000000000 +0100 @@ -751,6 +751,8 @@ static int pcm_trigger(struct snd_pcm_su spin_lock(&chip->lock); switch (cmd) { + case SNDRV_PCM_TRIGGER_RESUME: + DE_ACT(("pcm_trigger resume\n")); case SNDRV_PCM_TRIGGER_START: case SNDRV_PCM_TRIGGER_PAUSE_RELEASE: DE_ACT(("pcm_trigger start\n")); @@ -774,6 +776,8 @@ static int pcm_trigger(struct snd_pcm_su err = start_transport(chip, channelmask, chip->pipe_cyclic_mask); break; + case SNDRV_PCM_TRIGGER_SUSPEND: + DE_ACT(("pcm_trigger suspend\n")); case SNDRV_PCM_TRIGGER_STOP: DE_ACT(("pcm_trigger stop\n")); for (i = 0; i < DSP_MAXPIPES; i++) { @@ -1949,18 +1953,27 @@ static __devinit int snd_echo_create(str return err; pci_set_master(pci); - /* allocate a chip-specific data */ - chip = kzalloc(sizeof(*chip), GFP_KERNEL); - if (!chip) { - pci_disable_device(pci); - return -ENOMEM; + /* Allocate chip if needed */ + if (!*rchip) { + chip = kzalloc(sizeof(*chip), GFP_KERNEL); + if (!chip) { + pci_disable_device(pci); + return -ENOMEM; + } + DE_INIT(("chip=%p\n", chip)); + spin_lock_init(&chip->lock); + chip->card = card; + chip->pci = pci; + chip->irq = -1; + atomic_set(&chip->opencount, 0); + mutex_init(&chip->mode_mutex); + chip->can_set_rate = 1; + } else { + /* If this was called from the resume function, chip is + * already allocated and it contains current card settings. + */ + chip = *rchip; } - DE_INIT(("chip=%p\n", chip)); - - spin_lock_init(&chip->lock); - chip->card = card; - chip->pci = pci; - chip->irq = -1; /* PCI resource allocation */ chip->dsp_registers_phys = pci_resource_start(pci, 0); @@ -2000,7 +2013,9 @@ static __devinit int snd_echo_create(str chip->comm_page = (struct comm_page *)chip->commpage_dma_buf.area; err = init_hw(chip, chip->pci->device, chip->pci->subsystem_device); - if (err) { + if (err >= 0) + err = set_mixer_defaults(chip); + if (err < 0) { DE_INIT(("init_hw err=%d\n", err)); snd_echo_free(chip); return err; @@ -2011,9 +2026,6 @@ static __devinit int snd_echo_create(str snd_echo_free(chip); return err; } - atomic_set(&chip->opencount, 0); - mutex_init(&chip->mode_mutex); - chip->can_set_rate = 1; *rchip = chip; /* Init done ! */ return 0; @@ -2046,6 +2058,7 @@ static int __devinit snd_echo_probe(stru snd_card_set_dev(card, &pci->dev); + chip = NULL; /* Tells snd_echo_create to allocate chip */ if ((err = snd_echo_create(card, pci, &chip)) < 0) { snd_card_free(card); return err; @@ -2185,6 +2198,109 @@ ctl_error: +#if defined(CONFIG_PM) + +static int snd_echo_suspend(struct pci_dev *pci, pm_message_t state) +{ + struct echoaudio *chip = pci_get_drvdata(pci); + + DE_INIT(("suspend start\n")); + snd_pcm_suspend_all(chip->analog_pcm); + snd_pcm_suspend_all(chip->digital_pcm); + + spin_lock_irq(&chip->lock); + if (chip->meters_enabled) + send_vector(chip, DSP_VC_METERS_OFF); +#ifdef ECHOCARD_HAS_MIDI + if (chip->midi_input_enabled) + enable_midi_input(chip, FALSE); + if (chip->midi_out) + snd_echo_midi_output_trigger(chip->midi_out, 0); +#endif + send_vector(chip, DSP_VC_GO_COMATOSE); + spin_unlock_irq(&chip->lock); + + chip->dsp_code = NULL; + if (chip->irq >= 0) { + free_irq(chip->irq, chip); + chip->irq = -1; + } + + pci_save_state(pci); + pci_disable_device(pci); + DE_INIT(("suspend done\n")); + return 0; +} + + + +static int snd_echo_resume(struct pci_dev *pci) +{ + struct echoaudio *chip = pci_get_drvdata(pci); + struct comm_page *commpage, *commpage_bak; + u32 pipe_alloc_mask; + int err; + + DE_INIT(("resume start\n")); + pci_restore_state(pci); + commpage_bak = kmalloc(sizeof(struct echoaudio), GFP_KERNEL); + commpage = chip->comm_page; + memcpy(commpage_bak, commpage, sizeof(struct comm_page)); + + err = init_hw(chip, chip->pci->device, chip->pci->subsystem_device); + if (err < 0) { + kfree(commpage_bak); + DE_INIT(("resume init_hw err=%d\n", err)); + snd_echo_free(chip); + return err; + } + DE_INIT(("resume init OK\n")); + + /* Temporarily set chip->pipe_alloc_mask=0 otherwise + * restore_dsp_settings() fails. + */ + pipe_alloc_mask = chip->pipe_alloc_mask; + chip->pipe_alloc_mask = 0; + err = restore_dsp_rettings(chip); + chip->pipe_alloc_mask = pipe_alloc_mask; + if (err < 0) { + kfree(commpage_bak); + return err; + } + DE_INIT(("resume restore OK\n")); + + memcpy(&commpage->audio_format, &commpage_bak->audio_format, + sizeof(commpage->audio_format)); + memcpy(&commpage->sglist_addr, &commpage_bak->sglist_addr, + sizeof(commpage->sglist_addr)); + memcpy(&commpage->midi_output, &commpage_bak->midi_output, + sizeof(commpage->midi_output)); + kfree(commpage_bak); + + if (request_irq(pci->irq, snd_echo_interrupt, IRQF_SHARED, + ECHOCARD_NAME, chip)) { + snd_echo_free(chip); + snd_printk(KERN_ERR "cannot grab irq\n"); + return -EBUSY; + } + chip->irq = pci->irq; + DE_INIT(("resume irq=%d\n", chip->irq)); + +#ifdef ECHOCARD_HAS_MIDI + if (chip->midi_input_enabled) + enable_midi_input(chip, TRUE); + if (chip->midi_out) + snd_echo_midi_output_trigger(chip->midi_out, 1); +#endif + + DE_INIT(("resume done\n")); + return 0; +} + +#endif /* CONFIG_PM */ + + + static void __devexit snd_echo_remove(struct pci_dev *pci) { struct echoaudio *chip; @@ -2207,6 +2323,10 @@ static struct pci_driver driver = { .id_table = snd_echo_ids, .probe = snd_echo_probe, .remove = __devexit_p(snd_echo_remove), +#ifdef CONFIG_PM + .suspend = snd_echo_suspend, + .resume = snd_echo_resume, +#endif /* CONFIG_PM */ }; Only in alsa-driver-1.0.22.1/alsa-kernel/pci/echoaudio/: echoaudio.c~ diff -dup alsa-driver-1.0.22.1__orig/alsa-kernel/pci/echoaudio/echoaudio_dsp.c alsa-driver-1.0.22.1/alsa-kernel/pci/echoaudio/echoaudio_dsp.c --- alsa-driver-1.0.22.1__orig/alsa-kernel/pci/echoaudio/echoaudio_dsp.c 2010-01-07 21:43:00.000000000 +0100 +++ alsa-driver-1.0.22.1/alsa-kernel/pci/echoaudio/echoaudio_dsp.c 2010-01-01 22:15:54.000000000 +0100 @@ -497,9 +497,6 @@ static int load_firmware(struct echoaudi if ((box_type = load_asic(chip)) < 0) return box_type; /* error */ - if ((err = restore_dsp_rettings(chip)) < 0) - return err; - return box_type; } @@ -659,51 +656,106 @@ static void get_audio_meters(struct echo static int restore_dsp_rettings(struct echoaudio *chip) { - int err; + int i, o, err; DE_INIT(("restore_dsp_settings\n")); if ((err = check_asic_status(chip)) < 0) return err; - /* @ Gina20/Darla20 only. Should be harmless for other cards. */ + /* Gina20/Darla20 only. Should be harmless for other cards. */ chip->comm_page->gd_clock_state = GD_CLOCK_UNDEF; chip->comm_page->gd_spdif_status = GD_SPDIF_STATUS_UNDEF; chip->comm_page->handshake = 0xffffffff; - if ((err = set_sample_rate(chip, chip->sample_rate)) < 0) + /* Restore output busses */ + for (i = 0; i < num_busses_out(chip); i++) { + err = set_output_gain(chip, i, chip->output_gain[i]); + if (err < 0) + return err; + } + +#ifdef ECHOCARD_HAS_VMIXER + for (i = 0; i < num_pipes_out(chip); i++) + for (o = 0; o < num_busses_out(chip); o++) { + err = set_vmixer_gain(chip, o, i, + chip->vmixer_gain[o][i]); + if (err < 0) + return err; + } + if (update_vmixer_level(chip) < 0) + return -EIO; +#endif /* ECHOCARD_HAS_VMIXER */ + +#ifdef ECHOCARD_HAS_MONITOR + for (o = 0; o < num_busses_out(chip); o++) + for (i = 0; i < num_busses_in(chip); i++) { + err = set_monitor_gain(chip, o, i, + chip->monitor_gain[o][i]); + if (err < 0) + return err; + } +#endif /* ECHOCARD_HAS_MONITOR */ + +#ifdef ECHOCARD_HAS_INPUT_GAIN + for (i = 0; i < num_busses_in(chip); i++) { + err = set_input_gain(chip, i, chip->input_gain[i]); + if (err < 0) + return err; + } +#endif /* ECHOCARD_HAS_INPUT_GAIN */ + + err = update_output_line_level(chip); + if (err < 0) return err; - if (chip->meters_enabled) - if (send_vector(chip, DSP_VC_METERS_ON) < 0) - return -EIO; + err = update_input_line_level(chip); + if (err < 0) + return err; -#ifdef ECHOCARD_HAS_EXTERNAL_CLOCK - if (set_input_clock(chip, chip->input_clock) < 0) + err = set_sample_rate(chip, chip->sample_rate); + if (err < 0) + return err; + + if (chip->meters_enabled) { + err = send_vector(chip, DSP_VC_METERS_ON); + if (err < 0) + return err; + } + +#ifdef ECHOCARD_HAS_DIGITAL_MODE_SWITCH + if (set_digital_mode(chip, chip->digital_mode) < 0) return -EIO; #endif -#ifdef ECHOCARD_HAS_OUTPUT_CLOCK_SWITCH - if (set_output_clock(chip, chip->output_clock) < 0) +#ifdef ECHOCARD_HAS_DIGITAL_IO + if (set_professional_spdif(chip, chip->professional_spdif) < 0) return -EIO; #endif - if (update_output_line_level(chip) < 0) +#ifdef ECHOCARD_HAS_PHANTOM_POWER + if (set_phantom_power(chip, chip->phantom_power) < 0) return -EIO; +#endif - if (update_input_line_level(chip) < 0) +#ifdef ECHOCARD_HAS_EXTERNAL_CLOCK + /* set_input_clock() also restores automute setting */ + if (set_input_clock(chip, chip->input_clock) < 0) return -EIO; +#endif -#ifdef ECHOCARD_HAS_VMIXER - if (update_vmixer_level(chip) < 0) +#ifdef ECHOCARD_HAS_OUTPUT_CLOCK_SWITCH + if (set_output_clock(chip, chip->output_clock) < 0) return -EIO; #endif if (wait_handshake(chip) < 0) return -EIO; clear_handshake(chip); + if (send_vector(chip, DSP_VC_UPDATE_FLAGS) < 0) + return -EIO; DE_INIT(("restore_dsp_rettings done\n")); - return send_vector(chip, DSP_VC_UPDATE_FLAGS); + return 0; } @@ -920,9 +972,6 @@ static int init_dsp_comm_page(struct ech chip->card_name = ECHOCARD_NAME; chip->bad_board = TRUE; /* Set TRUE until DSP loaded */ chip->dsp_code = NULL; /* Current DSP code not loaded */ - chip->digital_mode = DIGITAL_MODE_NONE; - chip->input_clock = ECHO_CLOCK_INTERNAL; - chip->output_clock = ECHO_CLOCK_WORD; chip->asic_loaded = FALSE; memset(chip->comm_page, 0, sizeof(struct comm_page)); @@ -933,7 +982,6 @@ static int init_dsp_comm_page(struct ech chip->comm_page->midi_out_free_count = cpu_to_le32(DSP_MIDI_OUT_FIFO_SIZE); chip->comm_page->sample_rate = cpu_to_le32(44100); - chip->sample_rate = 44100; /* Set line levels so we don't blast any inputs on startup */ memset(chip->comm_page->monitors, ECHOGAIN_MUTED, MONITOR_ARRAY_SIZE); @@ -944,50 +992,21 @@ static int init_dsp_comm_page(struct ech -/* This function initializes the several volume controls for busses and pipes. -This MUST be called after the DSP is up and running ! */ +/* This function initializes the chip structure with default values, ie. all + * muted and internal clock source. Then it copies the settings to the DSP. + * This MUST be called after the DSP is up and running ! + */ static int init_line_levels(struct echoaudio *chip) { - int st, i, o; - DE_INIT(("init_line_levels\n")); - - /* Mute output busses */ - for (i = 0; i < num_busses_out(chip); i++) - if ((st = set_output_gain(chip, i, ECHOGAIN_MUTED))) - return st; - if ((st = update_output_line_level(chip))) - return st; - -#ifdef ECHOCARD_HAS_VMIXER - /* Mute the Vmixer */ - for (i = 0; i < num_pipes_out(chip); i++) - for (o = 0; o < num_busses_out(chip); o++) - if ((st = set_vmixer_gain(chip, o, i, ECHOGAIN_MUTED))) - return st; - if ((st = update_vmixer_level(chip))) - return st; -#endif /* ECHOCARD_HAS_VMIXER */ - -#ifdef ECHOCARD_HAS_MONITOR - /* Mute the monitor mixer */ - for (o = 0; o < num_busses_out(chip); o++) - for (i = 0; i < num_busses_in(chip); i++) - if ((st = set_monitor_gain(chip, o, i, ECHOGAIN_MUTED))) - return st; - if ((st = update_output_line_level(chip))) - return st; -#endif /* ECHOCARD_HAS_MONITOR */ - -#ifdef ECHOCARD_HAS_INPUT_GAIN - for (i = 0; i < num_busses_in(chip); i++) - if ((st = set_input_gain(chip, i, ECHOGAIN_MUTED))) - return st; - if ((st = update_input_line_level(chip))) - return st; -#endif /* ECHOCARD_HAS_INPUT_GAIN */ - - return 0; + memset(chip->output_gain, ECHOGAIN_MUTED, sizeof(chip->output_gain)); + memset(chip->input_gain, ECHOGAIN_MUTED, sizeof(chip->input_gain)); + memset(chip->monitor_gain, ECHOGAIN_MUTED, sizeof(chip->monitor_gain)); + memset(chip->vmixer_gain, ECHOGAIN_MUTED, sizeof(chip->vmixer_gain)); + chip->input_clock = ECHO_CLOCK_INTERNAL; + chip->output_clock = ECHO_CLOCK_WORD; + chip->sample_rate = 44100; + return restore_dsp_rettings(chip); } diff -dup alsa-driver-1.0.22.1__orig/alsa-kernel/pci/echoaudio/echoaudio.h alsa-driver-1.0.22.1/alsa-kernel/pci/echoaudio/echoaudio.h --- alsa-driver-1.0.22.1__orig/alsa-kernel/pci/echoaudio/echoaudio.h 2010-01-07 21:43:03.000000000 +0100 +++ alsa-driver-1.0.22.1/alsa-kernel/pci/echoaudio/echoaudio.h 2010-01-07 21:36:21.000000000 +0100 @@ -472,6 +472,8 @@ static void free_firmware(const struct f #ifdef ECHOCARD_HAS_MIDI static int enable_midi_input(struct echoaudio *chip, char enable); +static void snd_echo_midi_output_trigger( + struct snd_rawmidi_substream *substream, int up); static int midi_service_irq(struct echoaudio *chip); static int __devinit snd_echo_midi_create(struct snd_card *card, struct echoaudio *chip); Only in alsa-driver-1.0.22.1/alsa-kernel/pci/echoaudio/: echoaudio.h~ diff -dup alsa-driver-1.0.22.1__orig/alsa-kernel/pci/echoaudio/gina20_dsp.c alsa-driver-1.0.22.1/alsa-kernel/pci/echoaudio/gina20_dsp.c --- alsa-driver-1.0.22.1__orig/alsa-kernel/pci/echoaudio/gina20_dsp.c 2010-01-07 21:43:00.000000000 +0100 +++ alsa-driver-1.0.22.1/alsa-kernel/pci/echoaudio/gina20_dsp.c 2010-01-01 22:15:54.000000000 +0100 @@ -62,17 +62,20 @@ static int init_hw(struct echoaudio *chi return err; chip->bad_board = FALSE; - if ((err = init_line_levels(chip)) < 0) - return err; - - err = set_professional_spdif(chip, TRUE); - DE_INIT(("init_hw done\n")); return err; } +static int set_mixer_defaults(struct echoaudio *chip) +{ + chip->professional_spdif = FALSE; + return init_line_levels(chip); +} + + + static u32 detect_input_clocks(const struct echoaudio *chip) { u32 clocks_from_dsp, clock_bits; diff -dup alsa-driver-1.0.22.1__orig/alsa-kernel/pci/echoaudio/gina24_dsp.c alsa-driver-1.0.22.1/alsa-kernel/pci/echoaudio/gina24_dsp.c --- alsa-driver-1.0.22.1__orig/alsa-kernel/pci/echoaudio/gina24_dsp.c 2010-01-07 21:43:00.000000000 +0100 +++ alsa-driver-1.0.22.1/alsa-kernel/pci/echoaudio/gina24_dsp.c 2010-01-07 21:57:55.000000000 +0100 @@ -57,9 +57,6 @@ static int init_hw(struct echoaudio *chi ECHO_CLOCK_BIT_INTERNAL | ECHO_CLOCK_BIT_SPDIF | ECHO_CLOCK_BIT_ESYNC | ECHO_CLOCK_BIT_ESYNC96 | ECHO_CLOCK_BIT_ADAT; - chip->professional_spdif = FALSE; - chip->digital_in_automute = TRUE; - chip->digital_mode = DIGITAL_MODE_SPDIF_RCA; /* Gina24 comes in both '301 and '361 flavors */ if (chip->device_id == DEVICE_ID_56361) { @@ -81,19 +78,22 @@ static int init_hw(struct echoaudio *chi return err; chip->bad_board = FALSE; - if ((err = init_line_levels(chip)) < 0) - return err; - err = set_digital_mode(chip, DIGITAL_MODE_SPDIF_RCA); - if (err < 0) - return err; - err = set_professional_spdif(chip, TRUE); - DE_INIT(("init_hw done\n")); return err; } +static int set_mixer_defaults(struct echoaudio *chip) +{ + chip->digital_mode = DIGITAL_MODE_SPDIF_RCA; + chip->professional_spdif = FALSE; + chip->digital_in_automute = TRUE; + return init_line_levels(chip); +} + + + static u32 detect_input_clocks(const struct echoaudio *chip) { u32 clocks_from_dsp, clock_bits; Only in alsa-driver-1.0.22.1/alsa-kernel/pci/echoaudio/: gina24_dsp.c~ diff -dup alsa-driver-1.0.22.1__orig/alsa-kernel/pci/echoaudio/indigodj_dsp.c alsa-driver-1.0.22.1/alsa-kernel/pci/echoaudio/indigodj_dsp.c --- alsa-driver-1.0.22.1__orig/alsa-kernel/pci/echoaudio/indigodj_dsp.c 2010-01-07 21:43:00.000000000 +0100 +++ alsa-driver-1.0.22.1/alsa-kernel/pci/echoaudio/indigodj_dsp.c 2010-01-01 22:15:54.000000000 +0100 @@ -60,15 +60,19 @@ static int init_hw(struct echoaudio *chi return err; chip->bad_board = FALSE; - if ((err = init_line_levels(chip)) < 0) - return err; - DE_INIT(("init_hw done\n")); return err; } +static int set_mixer_defaults(struct echoaudio *chip) +{ + return init_line_levels(chip); +} + + + static u32 detect_input_clocks(const struct echoaudio *chip) { return ECHO_CLOCK_BIT_INTERNAL; diff -dup alsa-driver-1.0.22.1__orig/alsa-kernel/pci/echoaudio/indigodjx_dsp.c alsa-driver-1.0.22.1/alsa-kernel/pci/echoaudio/indigodjx_dsp.c --- alsa-driver-1.0.22.1__orig/alsa-kernel/pci/echoaudio/indigodjx_dsp.c 2010-01-07 21:43:00.000000000 +0100 +++ alsa-driver-1.0.22.1/alsa-kernel/pci/echoaudio/indigodjx_dsp.c 2010-01-01 22:15:54.000000000 +0100 @@ -59,10 +59,13 @@ static int init_hw(struct echoaudio *chi return err; chip->bad_board = FALSE; - err = init_line_levels(chip); - if (err < 0) - return err; - DE_INIT(("init_hw done\n")); return err; } + + + +static int set_mixer_defaults(struct echoaudio *chip) +{ + return init_line_levels(chip); +} diff -dup alsa-driver-1.0.22.1__orig/alsa-kernel/pci/echoaudio/indigo_dsp.c alsa-driver-1.0.22.1/alsa-kernel/pci/echoaudio/indigo_dsp.c --- alsa-driver-1.0.22.1__orig/alsa-kernel/pci/echoaudio/indigo_dsp.c 2010-01-07 21:43:00.000000000 +0100 +++ alsa-driver-1.0.22.1/alsa-kernel/pci/echoaudio/indigo_dsp.c 2010-01-01 22:15:54.000000000 +0100 @@ -60,15 +60,19 @@ static int init_hw(struct echoaudio *chi return err; chip->bad_board = FALSE; - if ((err = init_line_levels(chip)) < 0) - return err; - DE_INIT(("init_hw done\n")); return err; } +static int set_mixer_defaults(struct echoaudio *chip) +{ + return init_line_levels(chip); +} + + + static u32 detect_input_clocks(const struct echoaudio *chip) { return ECHO_CLOCK_BIT_INTERNAL; diff -dup alsa-driver-1.0.22.1__orig/alsa-kernel/pci/echoaudio/indigo_express_dsp.c alsa-driver-1.0.22.1/alsa-kernel/pci/echoaudio/indigo_express_dsp.c --- alsa-driver-1.0.22.1__orig/alsa-kernel/pci/echoaudio/indigo_express_dsp.c 2009-12-28 15:21:33.000000000 +0100 +++ alsa-driver-1.0.22.1/alsa-kernel/pci/echoaudio/indigo_express_dsp.c 2010-01-01 22:15:54.000000000 +0100 @@ -61,6 +61,7 @@ static int set_sample_rate(struct echoau control_reg |= clock; if (control_reg != old_control_reg) { + DE_ACT(("set_sample_rate: %d clock %d\n", rate, clock)); chip->comm_page->control_register = cpu_to_le32(control_reg); chip->sample_rate = rate; clear_handshake(chip); diff -dup alsa-driver-1.0.22.1__orig/alsa-kernel/pci/echoaudio/indigoio_dsp.c alsa-driver-1.0.22.1/alsa-kernel/pci/echoaudio/indigoio_dsp.c --- alsa-driver-1.0.22.1__orig/alsa-kernel/pci/echoaudio/indigoio_dsp.c 2010-01-07 21:43:00.000000000 +0100 +++ alsa-driver-1.0.22.1/alsa-kernel/pci/echoaudio/indigoio_dsp.c 2010-01-01 22:15:54.000000000 +0100 @@ -60,15 +60,19 @@ static int init_hw(struct echoaudio *chi return err; chip->bad_board = FALSE; - if ((err = init_line_levels(chip)) < 0) - return err; - DE_INIT(("init_hw done\n")); return err; } +static int set_mixer_defaults(struct echoaudio *chip) +{ + return init_line_levels(chip); +} + + + static u32 detect_input_clocks(const struct echoaudio *chip) { return ECHO_CLOCK_BIT_INTERNAL; diff -dup alsa-driver-1.0.22.1__orig/alsa-kernel/pci/echoaudio/indigoiox_dsp.c alsa-driver-1.0.22.1/alsa-kernel/pci/echoaudio/indigoiox_dsp.c --- alsa-driver-1.0.22.1__orig/alsa-kernel/pci/echoaudio/indigoiox_dsp.c 2010-01-07 21:43:00.000000000 +0100 +++ alsa-driver-1.0.22.1/alsa-kernel/pci/echoaudio/indigoiox_dsp.c 2010-01-01 22:15:54.000000000 +0100 @@ -59,10 +59,13 @@ static int init_hw(struct echoaudio *chi return err; chip->bad_board = FALSE; - err = init_line_levels(chip); - if (err < 0) - return err; - DE_INIT(("init_hw done\n")); return err; } + + + +static int set_mixer_defaults(struct echoaudio *chip) +{ + return init_line_levels(chip); +} diff -dup alsa-driver-1.0.22.1__orig/alsa-kernel/pci/echoaudio/layla20_dsp.c alsa-driver-1.0.22.1/alsa-kernel/pci/echoaudio/layla20_dsp.c --- alsa-driver-1.0.22.1__orig/alsa-kernel/pci/echoaudio/layla20_dsp.c 2010-01-07 21:43:00.000000000 +0100 +++ alsa-driver-1.0.22.1/alsa-kernel/pci/echoaudio/layla20_dsp.c 2010-01-07 22:02:47.000000000 +0100 @@ -64,17 +64,20 @@ static int init_hw(struct echoaudio *chi return err; chip->bad_board = FALSE; - if ((err = init_line_levels(chip)) < 0) - return err; - - err = set_professional_spdif(chip, TRUE); - DE_INIT(("init_hw done\n")); return err; } +static int set_mixer_defaults(struct echoaudio *chip) +{ + chip->professional_spdif = FALSE; + return init_line_levels(chip); +} + + + static u32 detect_input_clocks(const struct echoaudio *chip) { u32 clocks_from_dsp, clock_bits; Only in alsa-driver-1.0.22.1/alsa-kernel/pci/echoaudio/: layla20_dsp.c~ diff -dup alsa-driver-1.0.22.1__orig/alsa-kernel/pci/echoaudio/layla24_dsp.c alsa-driver-1.0.22.1/alsa-kernel/pci/echoaudio/layla24_dsp.c --- alsa-driver-1.0.22.1__orig/alsa-kernel/pci/echoaudio/layla24_dsp.c 2010-01-07 21:43:00.000000000 +0100 +++ alsa-driver-1.0.22.1/alsa-kernel/pci/echoaudio/layla24_dsp.c 2010-01-07 22:04:26.000000000 +0100 @@ -61,9 +61,6 @@ static int init_hw(struct echoaudio *chi ECHOCAPS_HAS_DIGITAL_MODE_SPDIF_RCA | ECHOCAPS_HAS_DIGITAL_MODE_SPDIF_OPTICAL | ECHOCAPS_HAS_DIGITAL_MODE_ADAT; - chip->digital_mode = DIGITAL_MODE_SPDIF_RCA; - chip->professional_spdif = FALSE; - chip->digital_in_automute = TRUE; if ((err = load_firmware(chip)) < 0) return err; @@ -72,17 +69,22 @@ static int init_hw(struct echoaudio *chi if ((err = init_line_levels(chip)) < 0) return err; - err = set_digital_mode(chip, DIGITAL_MODE_SPDIF_RCA); - if (err < 0) - return err; - err = set_professional_spdif(chip, TRUE); - DE_INIT(("init_hw done\n")); return err; } +static int set_mixer_defaults(struct echoaudio *chip) +{ + chip->digital_mode = DIGITAL_MODE_SPDIF_RCA; + chip->professional_spdif = FALSE; + chip->digital_in_automute = TRUE; + return init_line_levels(chip); +} + + + static u32 detect_input_clocks(const struct echoaudio *chip) { u32 clocks_from_dsp, clock_bits; Only in alsa-driver-1.0.22.1/alsa-kernel/pci/echoaudio/: layla24_dsp.c~ diff -dup alsa-driver-1.0.22.1__orig/alsa-kernel/pci/echoaudio/mia_dsp.c alsa-driver-1.0.22.1/alsa-kernel/pci/echoaudio/mia_dsp.c --- alsa-driver-1.0.22.1__orig/alsa-kernel/pci/echoaudio/mia_dsp.c 2010-01-07 21:43:00.000000000 +0100 +++ alsa-driver-1.0.22.1/alsa-kernel/pci/echoaudio/mia_dsp.c 2010-01-01 22:15:54.000000000 +0100 @@ -66,15 +66,19 @@ static int init_hw(struct echoaudio *chi return err; chip->bad_board = FALSE; - if ((err = init_line_levels(chip))) - return err; - DE_INIT(("init_hw done\n")); return err; } +static int set_mixer_defaults(struct echoaudio *chip) +{ + return init_line_levels(chip); +} + + + static u32 detect_input_clocks(const struct echoaudio *chip) { u32 clocks_from_dsp, clock_bits; diff -dup alsa-driver-1.0.22.1__orig/alsa-kernel/pci/echoaudio/mona_dsp.c alsa-driver-1.0.22.1/alsa-kernel/pci/echoaudio/mona_dsp.c --- alsa-driver-1.0.22.1__orig/alsa-kernel/pci/echoaudio/mona_dsp.c 2010-01-07 21:43:00.000000000 +0100 +++ alsa-driver-1.0.22.1/alsa-kernel/pci/echoaudio/mona_dsp.c 2010-01-07 21:56:15.000000000 +0100 @@ -67,28 +67,26 @@ static int init_hw(struct echoaudio *chi else chip->dsp_code_to_load = FW_MONA_301_DSP; - chip->digital_mode = DIGITAL_MODE_SPDIF_RCA; - chip->professional_spdif = FALSE; - chip->digital_in_automute = TRUE; - if ((err = load_firmware(chip)) < 0) return err; chip->bad_board = FALSE; - if ((err = init_line_levels(chip)) < 0) - return err; - - err = set_digital_mode(chip, DIGITAL_MODE_SPDIF_RCA); - if (err < 0) - return err; - err = set_professional_spdif(chip, TRUE); - DE_INIT(("init_hw done\n")); return err; } +static int set_mixer_defaults(struct echoaudio *chip) +{ + chip->digital_mode = DIGITAL_MODE_SPDIF_RCA; + chip->professional_spdif = FALSE; + chip->digital_in_automute = TRUE; + return init_line_levels(chip); +} + + + static u32 detect_input_clocks(const struct echoaudio *chip) { u32 clocks_from_dsp, clock_bits; Only in alsa-driver-1.0.22.1/alsa-kernel/pci/echoaudio/: mona_dsp.c~ --- alsa-driver-1.0.22.1__orig/pci/echoaudio/echoaudio.patch 2009-12-28 16:15:54.000000000 +0100 +++ alsa-driver-1.0.22.1/pci/echoaudio/echoaudio.patch 2010-01-07 22:19:15.000000000 +0100 @@ -1,6 +1,6 @@ ---- ../../alsa-kernel/pci/echoaudio/echoaudio.c 2006-08-05 14:41:12.000000000 +0200 -+++ echoaudio.c 2006-10-07 20:30:53.000000000 +0200 -@@ -1926,6 +1926,7 @@ +--- ../../alsa-kernel/pci/echoaudio/echoaudio.c__orig 2010-01-07 21:48:51.000000000 +0100 ++++ echoaudio.c 2010-01-07 22:19:00.000000000 +0100 +@@ -1941,6 +1941,7 @@ static __devinit int snd_echo_create(str struct echoaudio *chip; int err; size_t sz; @@ -8,7 +8,7 @@ static struct snd_device_ops ops = { .dev_free = snd_echo_dev_free, }; -@@ -1988,7 +1989,12 @@ +@@ -2012,7 +2013,13 @@ static __devinit int snd_echo_create(str chip->comm_page_phys = chip->commpage_dma_buf.addr; chip->comm_page = (struct comm_page *)chip->commpage_dma_buf.area; @@ -19,6 +19,29 @@ + pci_read_config_word(pci, PCI_SUBSYSTEM_ID, &subsystem_device); +#endif + err = init_hw(chip, chip->pci->device, subsystem_device); - if (err) { - DE_INIT(("init_hw err=%d\n", err)); - snd_echo_free(chip); ++ + if (err >= 0) + err = set_mixer_defaults(chip); + if (err < 0) { +@@ -2240,6 +2247,7 @@ static int snd_echo_resume(struct pci_de + struct comm_page *commpage, *commpage_bak; + u32 pipe_alloc_mask; + int err; ++ u16 subsystem_device; + + DE_INIT(("resume start\n")); + pci_restore_state(pci); +@@ -2247,7 +2255,12 @@ static int snd_echo_resume(struct pci_de + commpage = chip->comm_page; + memcpy(commpage_bak, commpage, sizeof(struct comm_page)); + +- err = init_hw(chip, chip->pci->device, chip->pci->subsystem_device); ++#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 3, 0) ++ subsystem_device = pci->subsystem_device; ++#else ++ pci_read_config_word(pci, PCI_SUBSYSTEM_ID, &subsystem_device); ++#endif ++ err = init_hw(chip, chip->pci->device, subsystem_device); + if (err < 0) { + kfree(commpage_bak); + DE_INIT(("resume init_hw err=%d\n", err));