static int set_input_clock(struct echoaudio *chip, u16 clock) { DE_ACT(("set_input_clock:\n")); switch (clock) { case ECHO_CLOCK_INTERNAL: /* Reset the audio state to unknown (just in case) */ chip->clock_state = GD_CLOCK_UNDEF; chip->spdif_status = GD_SPDIF_STATUS_UNDEF; set_sample_rate(chip, chip->sample_rate); chip->input_clock = clock; DE_ACT(("Set Gina clock to INTERNAL\n")); break; case ECHO_CLOCK_SPDIF: chip->comm_page->gd_clock_state = GD_CLOCK_SPDIFIN; chip->comm_page->gd_spdif_status = GD_SPDIF_STATUS_NOCHANGE; clear_handshake(chip); send_vector(chip, DSP_VC_SET_GD_AUDIO_STATE); chip->clock_state = GD_CLOCK_SPDIFIN; DE_ACT(("Set Gina20 clock to SPDIF\n")); chip->input_clock = clock; break; default: return -EINVAL; } return 0; }
static int update_input_line_level(struct echoaudio *chip) { if (wait_handshake(chip)) return -EIO; clear_handshake(chip); return send_vector(chip, DSP_VC_UPDATE_INGAIN); }
static int check_asic_status(struct echoaudio *chip) { u32 box_status; if (wait_handshake(chip)) return -EIO; chip->comm_page->ext_box_status = __constant_cpu_to_le32(E3G_ASIC_NOT_LOADED); chip->asic_loaded = FALSE; clear_handshake(chip); send_vector(chip, DSP_VC_TEST_ASIC); if (wait_handshake(chip)) { chip->dsp_code = NULL; return -EIO; } box_status = le32_to_cpu(chip->comm_page->ext_box_status); DE_INIT(("box_status=%x\n", box_status)); if (box_status == E3G_ASIC_NOT_LOADED) return -ENODEV; chip->asic_loaded = TRUE; return box_status & E3G_BOX_TYPE_MASK; }
/* Tell the DSP to reread the flags from the comm page */ static int update_flags(struct echoaudio *chip) { if (wait_handshake(chip)) return -EIO; clear_handshake(chip); return send_vector(chip, DSP_VC_UPDATE_FLAGS); }
/* Tell the DSP to read and update virtual mixer levels in comm page. */ static int update_vmixer_level(struct echoaudio *chip) { if (wait_handshake(chip)) return -EIO; clear_handshake(chip); return send_vector(chip, DSP_VC_SET_VMIXER_GAIN); }
static int set_sample_rate(struct echoaudio *chip, u32 rate) { if (wait_handshake(chip)) return -EIO; chip->sample_rate = rate; chip->comm_page->sample_rate = cpu_to_le32(rate); clear_handshake(chip); return send_vector(chip, DSP_VC_UPDATE_CLOCKS); }
static int set_sample_rate(struct echoaudio *chip, u32 rate) { u8 clock; switch (rate) { case 96000: clock = GD24_96000; break; case 88200: clock = GD24_88200; break; case 48000: clock = GD24_48000; break; case 44100: clock = GD24_44100; break; case 32000: clock = GD24_32000; break; case 22050: clock = GD24_22050; break; case 16000: clock = GD24_16000; break; case 11025: clock = GD24_11025; break; case 8000: clock = GD24_8000; break; default: DE_ACT(("set_sample_rate: Error, invalid sample rate %d\n", rate)); return -EINVAL; } if (wait_handshake(chip)) return -EIO; DE_ACT(("set_sample_rate: %d clock %d\n", rate, clock)); chip->sample_rate = rate; /* Override the sample rate if this card is set to Echo sync. */ if (chip->input_clock == ECHO_CLOCK_ESYNC) clock = GD24_EXT_SYNC; chip->comm_page->sample_rate = cpu_to_le32(rate); /* ignored by the DSP ? */ chip->comm_page->gd_clock_state = clock; clear_handshake(chip); return send_vector(chip, DSP_VC_SET_GD_AUDIO_STATE); }
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); }
/* Start and stop Midi input */ static int enable_midi_input(struct echoaudio *chip, char enable) { DE_MID(("enable_midi_input(%d)\n", enable)); if (wait_handshake(chip)) return -EIO; if (enable) { chip->mtc_state = MIDI_IN_STATE_NORMAL; chip->comm_page->flags |= cpu_to_le32(DSP_FLAG_MIDI_INPUT); } else chip->comm_page->flags &= ~cpu_to_le32(DSP_FLAG_MIDI_INPUT); clear_handshake(chip); return send_vector(chip, DSP_VC_UPDATE_FLAGS); }
static int set_sample_rate(struct echoaudio *chip, u32 rate) { u32 control_reg; switch (rate) { case 96000: control_reg = MIA_96000; break; case 88200: control_reg = MIA_88200; break; case 48000: control_reg = MIA_48000; break; case 44100: control_reg = MIA_44100; break; case 32000: control_reg = MIA_32000; break; default: DE_ACT(("set_sample_rate: %d invalid!\n", rate)); return -EINVAL; } /* Override the clock setting if this Mia is set to S/PDIF clock */ if (chip->input_clock == ECHO_CLOCK_SPDIF) control_reg |= MIA_SPDIF; /* Set the control register if it has changed */ if (control_reg != le32_to_cpu(chip->comm_page->control_register)) { if (wait_handshake(chip)) return -EIO; chip->comm_page->sample_rate = cpu_to_le32(rate); /* ignored by the DSP */ chip->comm_page->control_register = cpu_to_le32(control_reg); chip->sample_rate = rate; clear_handshake(chip); return send_vector(chip, DSP_VC_UPDATE_CLOCKS); } return 0; }
static int set_sample_rate(struct echoaudio *chip, u32 rate) { u32 clock, control_reg, old_control_reg; if (wait_handshake(chip)) return -EIO; old_control_reg = le32_to_cpu(chip->comm_page->control_register); control_reg = old_control_reg & ~INDIGO_EXPRESS_CLOCK_MASK; switch (rate) { case 32000: clock = INDIGO_EXPRESS_32000; break; case 44100: clock = INDIGO_EXPRESS_44100; break; case 48000: clock = INDIGO_EXPRESS_48000; break; case 64000: clock = INDIGO_EXPRESS_32000|INDIGO_EXPRESS_DOUBLE_SPEED; break; case 88200: clock = INDIGO_EXPRESS_44100|INDIGO_EXPRESS_DOUBLE_SPEED; break; case 96000: clock = INDIGO_EXPRESS_48000|INDIGO_EXPRESS_DOUBLE_SPEED; break; default: return -EINVAL; } 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); return send_vector(chip, DSP_VC_UPDATE_CLOCKS); } return 0; }
static int set_sample_rate(struct echoaudio *chip, u32 rate) { u8 clock_state, spdif_status; if (wait_handshake(chip)) return -EIO; switch (rate) { case 44100: clock_state = GD_CLOCK_44; spdif_status = GD_SPDIF_STATUS_44; break; case 48000: clock_state = GD_CLOCK_48; spdif_status = GD_SPDIF_STATUS_48; break; default: clock_state = GD_CLOCK_NOCHANGE; spdif_status = GD_SPDIF_STATUS_NOCHANGE; break; } if (chip->clock_state == clock_state) clock_state = GD_CLOCK_NOCHANGE; if (spdif_status == chip->spdif_status) spdif_status = GD_SPDIF_STATUS_NOCHANGE; chip->comm_page->sample_rate = cpu_to_le32(rate); chip->comm_page->gd_clock_state = clock_state; chip->comm_page->gd_spdif_status = spdif_status; chip->comm_page->gd_resampler_state = 3; /* magic number - should always be 3 */ /* Save the new audio state if it changed */ if (clock_state != GD_CLOCK_NOCHANGE) chip->clock_state = clock_state; if (spdif_status != GD_SPDIF_STATUS_NOCHANGE) chip->spdif_status = spdif_status; chip->sample_rate = rate; clear_handshake(chip); return send_vector(chip, DSP_VC_SET_GD_AUDIO_STATE); }
/* Send a buffer full of MIDI data to the DSP Returns how many actually written or < 0 on error */ static int write_midi(struct echoaudio *chip, u8 *data, int bytes) { if (snd_BUG_ON(bytes <= 0 || bytes >= MIDI_OUT_BUFFER_SIZE)) return -EINVAL; if (wait_handshake(chip)) return -EIO; /* HF4 indicates that it is safe to write MIDI output data */ if (! (get_dsp_register(chip, CHI32_STATUS_REG) & CHI32_STATUS_REG_HF4)) return 0; chip->comm_page->midi_output[0] = bytes; memcpy(&chip->comm_page->midi_output[1], data, bytes); chip->comm_page->midi_out_free_count = 0; clear_handshake(chip); send_vector(chip, DSP_VC_MIDI_WRITE); DE_MID(("write_midi: %d\n", bytes)); return bytes; }
static int set_input_clock(struct echoaudio *chip, u16 clock_source) { u16 clock; u32 rate; DE_ACT(("set_input_clock:\n")); rate = 0; switch (clock_source) { case ECHO_CLOCK_INTERNAL: DE_ACT(("Set Layla20 clock to INTERNAL\n")); rate = chip->sample_rate; clock = LAYLA20_CLOCK_INTERNAL; break; case ECHO_CLOCK_SPDIF: DE_ACT(("Set Layla20 clock to SPDIF\n")); clock = LAYLA20_CLOCK_SPDIF; break; case ECHO_CLOCK_WORD: DE_ACT(("Set Layla20 clock to WORD\n")); clock = LAYLA20_CLOCK_WORD; break; case ECHO_CLOCK_SUPER: DE_ACT(("Set Layla20 clock to SUPER\n")); clock = LAYLA20_CLOCK_SUPER; break; default: DE_ACT(("Input clock 0x%x not supported for Layla24\n", clock_source)); return -EINVAL; } chip->input_clock = clock_source; chip->comm_page->input_clock = cpu_to_le16(clock); clear_handshake(chip); send_vector(chip, DSP_VC_UPDATE_CLOCKS); if (rate) set_sample_rate(chip, rate); return 0; }
static int write_control_reg(struct echoaudio *chip, u32 value, char force) { /* Handle the digital input auto-mute */ if (chip->digital_in_automute) value |= GML_DIGITAL_IN_AUTO_MUTE; else value &= ~GML_DIGITAL_IN_AUTO_MUTE; DE_ACT(("write_control_reg: 0x%x\n", value)); /* Write the control register */ value = cpu_to_le32(value); if (value != chip->comm_page->control_register || force) { if (wait_handshake(chip)) return -EIO; chip->comm_page->control_register = value; clear_handshake(chip); return send_vector(chip, DSP_VC_WRITE_CONTROL_REG); } return 0; }
static int set_sample_rate(struct echoaudio *chip, u32 rate) { u32 control_reg; switch (rate) { case 96000: control_reg = MIA_96000; break; case 88200: control_reg = MIA_88200; break; case 48000: control_reg = MIA_48000; break; case 44100: control_reg = MIA_44100; break; case 32000: control_reg = MIA_32000; break; default: DE_ACT(("set_sample_rate: %d invalid!\n", rate)); return -EINVAL; } /* */ if (control_reg != le32_to_cpu(chip->comm_page->control_register)) { if (wait_handshake(chip)) return -EIO; chip->comm_page->sample_rate = cpu_to_le32(rate); /* */ chip->comm_page->control_register = cpu_to_le32(control_reg); chip->sample_rate = rate; clear_handshake(chip); return send_vector(chip, DSP_VC_UPDATE_CLOCKS); } return 0; }
/* Most configuration of 3G cards is accomplished by writing the control register. write_control_reg sends the new control register value to the DSP. */ static int write_control_reg(struct echoaudio *chip, u32 ctl, u32 frq, char force) { if (wait_handshake(chip)) return -EIO; DE_ACT(("WriteControlReg: Setting 0x%x, 0x%x\n", ctl, frq)); ctl = cpu_to_le32(ctl); frq = cpu_to_le32(frq); if (ctl != chip->comm_page->control_register || frq != chip->comm_page->e3g_frq_register || force) { chip->comm_page->e3g_frq_register = frq; chip->comm_page->control_register = ctl; clear_handshake(chip); return send_vector(chip, DSP_VC_WRITE_CONTROL_REG); } DE_ACT(("WriteControlReg: not written, no change\n")); return 0; }
static int set_output_clock(struct echoaudio *chip, u16 clock) { switch (clock) { case ECHO_CLOCK_SUPER: clock = LAYLA20_OUTPUT_CLOCK_SUPER; break; case ECHO_CLOCK_WORD: clock = LAYLA20_OUTPUT_CLOCK_WORD; break; default: dev_err(chip->card->dev, "set_output_clock wrong clock\n"); return -EINVAL; } if (wait_handshake(chip)) return -EIO; chip->comm_page->output_clock = cpu_to_le16(clock); chip->output_clock = clock; clear_handshake(chip); return send_vector(chip, DSP_VC_UPDATE_CLOCKS); }
/* start_transport starts transport for a set of pipes. The bits 1 in channel_mask specify what pipes to start. Only the bit of the first channel must be set, regardless its interleave. Same thing for pause_ and stop_ -trasport below. */ static int start_transport(struct echoaudio *chip, u32 channel_mask, u32 cyclic_mask) { if (wait_handshake(chip)) return -EIO; chip->comm_page->cmd_start |= cpu_to_le32(channel_mask); if (chip->comm_page->cmd_start) { clear_handshake(chip); send_vector(chip, DSP_VC_START_TRANSFER); if (wait_handshake(chip)) return -EIO; /* Keep track of which pipes are transporting */ chip->active_mask |= channel_mask; chip->comm_page->cmd_start = 0; return 0; } dev_err(chip->card->dev, "start_transport: No pipes to start!\n"); return -EINVAL; }
static int stop_transport(struct echoaudio *chip, u32 channel_mask) { if (wait_handshake(chip)) return -EIO; chip->comm_page->cmd_stop |= cpu_to_le32(channel_mask); chip->comm_page->cmd_reset |= cpu_to_le32(channel_mask); if (chip->comm_page->cmd_reset) { clear_handshake(chip); send_vector(chip, DSP_VC_STOP_TRANSFER); if (wait_handshake(chip)) return -EIO; /* Keep track of which pipes are transporting */ chip->active_mask &= ~channel_mask; chip->comm_page->cmd_stop = 0; chip->comm_page->cmd_reset = 0; return 0; } dev_warn(chip->card->dev, "stop_transport: No pipes to stop!\n"); return 0; }
static int start_transport(struct echoaudio *chip, u32 channel_mask, u32 cyclic_mask) { DE_ACT(("start_transport %x\n", channel_mask)); if (wait_handshake(chip)) return -EIO; chip->comm_page->cmd_start |= cpu_to_le32(channel_mask); if (chip->comm_page->cmd_start) { clear_handshake(chip); send_vector(chip, DSP_VC_START_TRANSFER); if (wait_handshake(chip)) return -EIO; /* */ chip->active_mask |= channel_mask; chip->comm_page->cmd_start = 0; return 0; } DE_ACT(("start_transport: No pipes to start!\n")); return -EINVAL; }
static int set_sample_rate(struct echoaudio *chip, u32 rate) { if (snd_BUG_ON(rate < 8000 || rate > 50000)) return -EINVAL; /* Only set the clock for internal mode. Do not return failure, simply treat it as a non-event. */ if (chip->input_clock != ECHO_CLOCK_INTERNAL) { dev_warn(chip->card->dev, "Cannot set sample rate - clock not set to CLK_CLOCKININTERNAL\n"); chip->comm_page->sample_rate = cpu_to_le32(rate); chip->sample_rate = rate; return 0; } if (wait_handshake(chip)) return -EIO; dev_dbg(chip->card->dev, "set_sample_rate(%d)\n", rate); chip->sample_rate = rate; chip->comm_page->sample_rate = cpu_to_le32(rate); clear_handshake(chip); return send_vector(chip, DSP_VC_SET_LAYLA_SAMPLE_RATE); }
static int stop_transport(struct echoaudio *chip, u32 channel_mask) { DE_ACT(("stop_transport %x\n", channel_mask)); if (wait_handshake(chip)) return -EIO; chip->comm_page->cmd_stop |= cpu_to_le32(channel_mask); chip->comm_page->cmd_reset |= cpu_to_le32(channel_mask); if (chip->comm_page->cmd_reset) { clear_handshake(chip); send_vector(chip, DSP_VC_STOP_TRANSFER); if (wait_handshake(chip)) return -EIO; /* */ chip->active_mask &= ~channel_mask; chip->comm_page->cmd_stop = 0; chip->comm_page->cmd_reset = 0; return 0; } DE_ACT(("stop_transport: No pipes to stop!\n")); return 0; }
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; }