static void get_audio_meters(struct echoaudio *chip, long *meters)
{
	int i, m, n;

	m = 0;
	n = 0;
	for (i = 0; i < num_busses_out(chip); i++, m++) {
		meters[n++] = chip->comm_page->vu_meter[m];
		meters[n++] = chip->comm_page->peak_meter[m];
	}
	for (; n < 32; n++)
		meters[n] = 0;

#ifdef ECHOCARD_ECHO3G
	m = E3G_MAX_OUTPUTS;	/*                    */
#endif

	for (i = 0; i < num_busses_in(chip); i++, m++) {
		meters[n++] = chip->comm_page->vu_meter[m];
		meters[n++] = chip->comm_page->peak_meter[m];
	}
	for (; n < 64; n++)
		meters[n] = 0;

#ifdef ECHOCARD_HAS_VMIXER
	for (i = 0; i < num_pipes_out(chip); i++, m++) {
		meters[n++] = chip->comm_page->vu_meter[m];
		meters[n++] = chip->comm_page->peak_meter[m];
	}
#endif
	for (; n < 96; n++)
		meters[n] = 0;
}
예제 #2
0
/* S/PDIF coax / S/PDIF optical / ADAT - switch */
static int set_digital_mode(struct echoaudio *chip, u8 mode)
{
	u8 previous_mode;
	int err, i, o;

	if (chip->bad_board)
		return -EIO;

	/* All audio channels must be closed before changing the digital mode */
	if (snd_BUG_ON(chip->pipe_alloc_mask))
		return -EAGAIN;

	if (snd_BUG_ON(!(chip->digital_modes & (1 << mode))))
		return -EINVAL;

	previous_mode = chip->digital_mode;
	err = dsp_set_digital_mode(chip, mode);

	/* If we successfully changed the digital mode from or to ADAT,
	   then make sure all output, input and monitor levels are
	   updated by the DSP comm object. */
	if (err >= 0 && previous_mode != mode &&
	    (previous_mode == DIGITAL_MODE_ADAT || mode == DIGITAL_MODE_ADAT)) {
		spin_lock_irq(&chip->lock);
		for (o = 0; o < num_busses_out(chip); o++)
			for (i = 0; i < num_busses_in(chip); i++)
				set_monitor_gain(chip, o, i,
						 chip->monitor_gain[o][i]);

#ifdef ECHOCARD_HAS_INPUT_GAIN
		for (i = 0; i < num_busses_in(chip); i++)
			set_input_gain(chip, i, chip->input_gain[i]);
		update_input_line_level(chip);
#endif

		for (o = 0; o < num_busses_out(chip); o++)
			set_output_gain(chip, o, chip->output_gain[o]);
		update_output_line_level(chip);
		spin_unlock_irq(&chip->lock);
	}

	return err;
}
예제 #3
0
/* This function initializes the several volume controls for busses and pipes.
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;
}
static int set_digital_mode(struct echoaudio *chip, u8 mode)
{
	u8 previous_mode;
	int err, i, o;

	if (chip->bad_board)
		return -EIO;

	
	if (snd_BUG_ON(chip->pipe_alloc_mask))
		return -EAGAIN;

	if (snd_BUG_ON(!(chip->digital_modes & (1 << mode))))
		return -EINVAL;

	previous_mode = chip->digital_mode;
	err = dsp_set_digital_mode(chip, mode);

	if (err >= 0 && previous_mode != mode &&
	    (previous_mode == DIGITAL_MODE_ADAT || mode == DIGITAL_MODE_ADAT)) {
		spin_lock_irq(&chip->lock);
		for (o = 0; o < num_busses_out(chip); o++)
			for (i = 0; i < num_busses_in(chip); i++)
				set_monitor_gain(chip, o, i,
						 chip->monitor_gain[o][i]);

#ifdef ECHOCARD_HAS_INPUT_GAIN
		for (i = 0; i < num_busses_in(chip); i++)
			set_input_gain(chip, i, chip->input_gain[i]);
		update_input_line_level(chip);
#endif

		for (o = 0; o < num_busses_out(chip); o++)
			set_output_gain(chip, o, chip->output_gain[o]);
		update_output_line_level(chip);
		spin_unlock_irq(&chip->lock);
	}

	return err;
}
예제 #5
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;
}
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;
}
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;
}