static int load_asic(struct echoaudio *chip) { int box_type, err; if (chip->asic_loaded) return 0; /* 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]); if (err < 0) return err; chip->asic_code = &card_fw[FW_3G_ASIC]; /* Now give the new ASIC some time to set up */ msleep(1000); /* See if it worked */ box_type = check_asic_status(chip); /* Set up the control register if the load succeeded - * 48 kHz, internal clock, S/PDIF RCA mode */ if (box_type >= 0) { err = write_control_reg(chip, E3G_48KHZ, E3G_FREQ_REG_DEFAULT, TRUE); if (err < 0) return err; } return box_type; }
static int load_firmware(struct echoaudio *chip) { const struct firmware *fw; int box_type, err; if (snd_BUG_ON(!chip->comm_page)) return -EPERM; /* */ if (chip->dsp_code) { if ((box_type = check_asic_status(chip)) >= 0) return box_type; /* */ chip->dsp_code = NULL; } 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); if (err < 0) return err; if ((box_type = load_asic(chip)) < 0) return box_type; /* */ return box_type; }
/* load_firmware takes care of loading the DSP and any ASIC code. */ static int load_firmware(struct echoaudio *chip) { const struct firmware *fw; int box_type, err; if (snd_BUG_ON(!chip->comm_page)) return -EPERM; /* See if the ASIC is present and working - only if the DSP is already loaded */ if (chip->dsp_code) { if ((box_type = check_asic_status(chip)) >= 0) return box_type; /* ASIC check failed; force the DSP to reload */ chip->dsp_code = NULL; } 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, chip); if (err < 0) return err; if ((box_type = load_asic(chip)) < 0) return box_type; /* error */ return box_type; }
/* Layla20 has an ASIC in the external box */ static int load_asic(struct echoaudio *chip) { int err; if (chip->asic_loaded) return 0; err = load_asic_generic(chip, DSP_FNC_LOAD_LAYLA_ASIC, &card_fw[FW_LAYLA20_ASIC]); if (err < 0) return err; /* Check if ASIC is alive and well. */ return check_asic_status(chip); }
static int restore_dsp_rettings(struct echoaudio *chip) { int 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. */ 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) return err; if (chip->meters_enabled) if (send_vector(chip, DSP_VC_METERS_ON) < 0) return -EIO; #ifdef ECHOCARD_HAS_EXTERNAL_CLOCK if (set_input_clock(chip, chip->input_clock) < 0) return -EIO; #endif #ifdef ECHOCARD_HAS_OUTPUT_CLOCK_SWITCH if (set_output_clock(chip, chip->output_clock) < 0) return -EIO; #endif if (update_output_line_level(chip) < 0) return -EIO; if (update_input_line_level(chip) < 0) return -EIO; #ifdef ECHOCARD_HAS_VMIXER if (update_vmixer_level(chip) < 0) return -EIO; #endif if (wait_handshake(chip) < 0) return -EIO; clear_handshake(chip); DE_INIT(("restore_dsp_rettings done\n")); return send_vector(chip, DSP_VC_UPDATE_FLAGS); }
/* Mona has an ASIC on the PCI card and another ASIC in the external box; both need to be loaded. */ static int load_asic(struct echoaudio *chip) { u32 control_reg; int err; short asic; if (chip->asic_loaded) return 0; mdelay(10); if (chip->device_id == DEVICE_ID_56361) asic = FW_MONA_361_1_ASIC48; else asic = FW_MONA_301_1_ASIC48; err = load_asic_generic(chip, DSP_FNC_LOAD_MONA_PCI_CARD_ASIC, asic); if (err < 0) return err; chip->asic_code = asic; mdelay(10); /* Do the external one */ err = load_asic_generic(chip, DSP_FNC_LOAD_MONA_EXTERNAL_ASIC, FW_MONA_2_ASIC); if (err < 0) return err; mdelay(10); err = check_asic_status(chip); /* Set up the control register if the load succeeded - 48 kHz, internal clock, S/PDIF RCA mode */ if (!err) { control_reg = GML_CONVERTER_ENABLE | GML_48KHZ; err = write_control_reg(chip, control_reg, true); } return err; }
/* Gina24 has an ASIC on the PCI card which must be loaded for anything interesting to happen. */ static int load_asic(struct echoaudio *chip) { u32 control_reg; int err; short asic; if (chip->asic_loaded) return 1; /* Give the DSP a few milliseconds to settle down */ mdelay(10); /* Pick the correct ASIC for '301 or '361 Gina24 */ if (chip->device_id == DEVICE_ID_56361) asic = FW_GINA24_361_ASIC; else asic = FW_GINA24_301_ASIC; err = load_asic_generic(chip, DSP_FNC_LOAD_GINA24_ASIC, asic); if (err < 0) return err; chip->asic_code = asic; /* Now give the new ASIC a little time to set up */ mdelay(10); /* See if it worked */ err = check_asic_status(chip); /* Set up the control register if the load succeeded - 48 kHz, internal clock, S/PDIF RCA mode */ if (!err) { control_reg = GML_CONVERTER_ENABLE | GML_48KHZ; err = write_control_reg(chip, control_reg, TRUE); } DE_INIT(("load_asic() done\n")); return err; }
static int load_asic(struct echoaudio *chip) { u32 control_reg; int err; short asic; if (chip->asic_loaded) return 1; mdelay(10); if (chip->device_id == DEVICE_ID_56361) asic = FW_GINA24_361_ASIC; else asic = FW_GINA24_301_ASIC; err = load_asic_generic(chip, DSP_FNC_LOAD_GINA24_ASIC, asic); if (err < 0) return err; chip->asic_code = asic; mdelay(10); err = check_asic_status(chip); if (!err) { control_reg = GML_CONVERTER_ENABLE | GML_48KHZ; err = write_control_reg(chip, control_reg, TRUE); } DE_INIT(("load_asic() done\n")); return err; }
static int restore_dsp_rettings(struct echoaudio *chip) { int i, o, err; DE_INIT(("restore_dsp_settings\n")); if ((err = check_asic_status(chip)) < 0) return err; /* */ chip->comm_page->gd_clock_state = GD_CLOCK_UNDEF; chip->comm_page->gd_spdif_status = GD_SPDIF_STATUS_UNDEF; chip->comm_page->handshake = 0xffffffff; /* */ 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 /* */ #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 /* */ #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 /* */ err = update_output_line_level(chip); if (err < 0) return err; err = update_input_line_level(chip); if (err < 0) return err; 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_DIGITAL_IO if (set_professional_spdif(chip, chip->professional_spdif) < 0) return -EIO; #endif #ifdef ECHOCARD_HAS_PHANTOM_POWER if (set_phantom_power(chip, chip->phantom_power) < 0) return -EIO; #endif #ifdef ECHOCARD_HAS_EXTERNAL_CLOCK /* */ if (set_input_clock(chip, chip->input_clock) < 0) return -EIO; #endif #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 0; }