/* Most configuration of 3G cards is accomplished by writing the control
register. write_control_reg sends the new control register value to the DSP. */ staticint write_control_reg(struct echoaudio *chip, u32 ctl, u32 frq, char force)
{
__le32 ctl_reg, frq_reg;
dev_dbg(chip->card->dev, "WriteControlReg: not written, no change\n"); return0;
}
/* Set the digital mode - currently for Gina24, Layla24, Mona, 3G */ staticint set_digital_mode(struct echoaudio *chip, u8 mode)
{
u8 previous_mode; int err, i, o;
/* 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;
/* If we successfully changed the digital mode from or to ADAT, *thenmakesurealloutput,inputandmonitorlevelsare
* 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);
}
/* detect_input_clocks() returns a bitmask consisting of all the input clocks currentlyconnectedtothehardware;thischangesastheuserconnectsand disconnectsclockinputs.Youshouldusethisinformationtodeterminewhich
clocks the user is allowed to select. */ static u32 detect_input_clocks(conststruct echoaudio *chip)
{
u32 clocks_from_dsp, clock_bits;
/* Map the DSP clock detect bits to the generic driver clock
* detect bits */
clocks_from_dsp = le32_to_cpu(chip->comm_page->status_clocks);
clock_bits = ECHO_CLOCK_BIT_INTERNAL;
if (clocks_from_dsp & E3G_CLOCK_DETECT_BIT_WORD)
clock_bits |= ECHO_CLOCK_BIT_WORD;
switch(chip->digital_mode) { case DIGITAL_MODE_SPDIF_RCA: case DIGITAL_MODE_SPDIF_OPTICAL: if (clocks_from_dsp & E3G_CLOCK_DETECT_BIT_SPDIF)
clock_bits |= ECHO_CLOCK_BIT_SPDIF; break; case DIGITAL_MODE_ADAT: if (clocks_from_dsp & E3G_CLOCK_DETECT_BIT_ADAT)
clock_bits |= ECHO_CLOCK_BIT_ADAT; break;
}
return clock_bits;
}
staticint load_asic(struct echoaudio *chip)
{ int box_type, err;
if (chip->asic_loaded) return0;
/* Give the DSP a few milliseconds to settle down */
mdelay(2);
/* 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;
}
/* Only set the clock for internal mode. */ if (chip->input_clock != ECHO_CLOCK_INTERNAL) {
dev_warn(chip->card->dev, "Cannot set sample rate - clock not set to CLK_CLOCKININTERNAL\n"); /* Save the rate anyhow */
chip->comm_page->sample_rate = cpu_to_le32(rate);
chip->sample_rate = rate;
set_input_clock(chip, chip->input_clock); return0;
}
if (snd_BUG_ON(rate >= 50000 &&
chip->digital_mode == DIGITAL_MODE_ADAT)) return -EINVAL;
/* Set clock to "internal" if it's not compatible with the new mode */
incompatible_clock = false; switch (mode) { case DIGITAL_MODE_SPDIF_OPTICAL: case DIGITAL_MODE_SPDIF_RCA: if (chip->input_clock == ECHO_CLOCK_ADAT)
incompatible_clock = true; break; case DIGITAL_MODE_ADAT: if (chip->input_clock == ECHO_CLOCK_SPDIF)
incompatible_clock = true; break; default:
dev_err(chip->card->dev, "Digital mode not supported: %d\n", mode); return -EINVAL;
}
spin_lock_irq(&chip->lock);
if (incompatible_clock) {
chip->sample_rate = 48000;
set_input_clock(chip, ECHO_CLOCK_INTERNAL);
}
/* Clear the current digital mode */
control_reg = le32_to_cpu(chip->comm_page->control_register);
control_reg &= E3G_DIGITAL_MODE_CLEAR_MASK;
/* Tweak the control reg */ switch (mode) { case DIGITAL_MODE_SPDIF_OPTICAL:
control_reg |= E3G_SPDIF_OPTICAL_MODE; break; case DIGITAL_MODE_SPDIF_RCA: /* E3G_SPDIF_OPTICAL_MODE bit cleared */ break; case DIGITAL_MODE_ADAT:
control_reg |= E3G_ADAT_MODE;
control_reg &= ~E3G_DOUBLE_SPEED_MODE; /* @@ useless */ break;
}
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.