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;
}
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);
}
Пример #3
0
/* 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);
}
Пример #4
0
/* 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);
}
Пример #5
0
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);
}
Пример #6
0
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 set_output_gain(struct echoaudio *chip, u16 channel, s8 gain)
{
	if (snd_BUG_ON(channel >= num_busses_out(chip)))
		return -EINVAL;

	if (wait_handshake(chip))
		return -EIO;

	/*                    */
	chip->output_gain[channel] = gain;
	chip->comm_page->line_out_level[channel] = gain;
	return 0;
}
Пример #8
0
/* Set input bus gain (one unit is 0.5dB !) */
static int set_input_gain(struct echoaudio *chip, u16 input, int gain)
{
	if (snd_BUG_ON(input >= num_busses_in(chip)))
		return -EINVAL;

	if (wait_handshake(chip))
		return -EIO;

	chip->input_gain[input] = gain;
	gain += GL20_INPUT_GAIN_MAGIC_NUMBER;
	chip->comm_page->line_in_level[input] = gain;
	return 0;
}
static int set_monitor_gain(struct echoaudio *chip, u16 output, u16 input,
			    s8 gain)
{
	if (snd_BUG_ON(output >= num_busses_out(chip) ||
		    input >= num_busses_in(chip)))
		return -EINVAL;

	if (wait_handshake(chip))
		return -EIO;

	chip->monitor_gain[output][input] = gain;
	chip->comm_page->monitors[monitor_index(chip, output, input)] = gain;
	return 0;
}
Пример #10
0
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;
}
Пример #11
0
/* 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 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 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;
}
Пример #14
0
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);
}
Пример #15
0
/* 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_nominal_level(struct echoaudio *chip, u16 index, char consumer)
{
	if (snd_BUG_ON(index >= num_busses_out(chip) + num_busses_in(chip)))
		return -EINVAL;

	/*                                                        */
	if (wait_handshake(chip))
		return -EIO;

	chip->nominal_level[index] = consumer;

	if (consumer)
		chip->comm_page->nominal_level_mask |= cpu_to_le32(1 << index);
	else
		chip->comm_page->nominal_level_mask &= ~cpu_to_le32(1 << index);

	return 0;
}
Пример #17
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;
}
Пример #18
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;
	}

	/* 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;
}
Пример #19
0
/* This function routes the sound from a virtual channel to a real output */
static int set_vmixer_gain(struct echoaudio *chip, u16 output, u16 pipe,
			   int gain)
{
	int index;

	if (snd_BUG_ON(pipe >= num_pipes_out(chip) ||
		       output >= num_busses_out(chip)))
		return -EINVAL;

	if (wait_handshake(chip))
		return -EIO;

	chip->vmixer_gain[output][pipe] = gain;
	index = output * num_pipes_out(chip) + pipe;
	chip->comm_page->vmixer[index] = gain;

	DE_ACT(("set_vmixer_gain: pipe %d, out %d = %d\n", pipe, output, gain));
	return 0;
}
Пример #20
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);
}
Пример #21
0
/* 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;
}
Пример #22
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;
}
Пример #23
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;
}
Пример #25
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);
}
Пример #26
0
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 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;
}