diff options
Diffstat (limited to 'sound/pci/echoaudio/echoaudio_dsp.c')
-rw-r--r-- | sound/pci/echoaudio/echoaudio_dsp.c | 157 |
1 files changed, 89 insertions, 68 deletions
diff --git a/sound/pci/echoaudio/echoaudio_dsp.c b/sound/pci/echoaudio/echoaudio_dsp.c index 4df51ef5e09..64417a73322 100644 --- a/sound/pci/echoaudio/echoaudio_dsp.c +++ b/sound/pci/echoaudio/echoaudio_dsp.c @@ -175,15 +175,15 @@ static inline int check_asic_status(struct echoaudio *chip) #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(struct echoaudio *chip) 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 echoaudio *chip) 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); @@ -495,9 +497,6 @@ static int load_firmware(struct echoaudio *chip) if ((box_type = load_asic(chip)) < 0) return box_type; /* error */ - if ((err = restore_dsp_rettings(chip)) < 0) - return err; - return box_type; } @@ -657,51 +656,106 @@ static void get_audio_meters(struct echoaudio *chip, long *meters) 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; } @@ -918,9 +972,6 @@ static int init_dsp_comm_page(struct echoaudio *chip) 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)); @@ -931,7 +982,6 @@ static int init_dsp_comm_page(struct echoaudio *chip) 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); @@ -942,50 +992,21 @@ static int init_dsp_comm_page(struct echoaudio *chip) -/* 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); } |