/* 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 & GML_CLOCK_DETECT_BIT_SPDIF)
clock_bits |= ECHO_CLOCK_BIT_SPDIF;
if (clocks_from_dsp & GML_CLOCK_DETECT_BIT_ADAT)
clock_bits |= ECHO_CLOCK_BIT_ADAT;
if (clocks_from_dsp & GML_CLOCK_DETECT_BIT_WORD)
clock_bits |= ECHO_CLOCK_BIT_WORD;
return clock_bits;
}
/* Layla24 has an ASIC on the PCI card and another ASIC in the external box;
both need to be loaded. */ staticint load_asic(struct echoaudio *chip)
{ int err;
if (chip->asic_loaded) return1;
/* Give the DSP a few milliseconds to settle down */
mdelay(10);
/* Load the ASIC for the PCI card */
err = load_asic_generic(chip, DSP_FNC_LOAD_LAYLA24_PCI_CARD_ASIC,
FW_LAYLA24_1_ASIC); if (err < 0) return err;
chip->asic_code = FW_LAYLA24_2S_ASIC;
/* Now give the new ASIC a little time to set up */
mdelay(10);
/* Do the external one */
err = load_asic_generic(chip, DSP_FNC_LOAD_LAYLA24_EXTERNAL_ASIC,
FW_LAYLA24_2S_ASIC); if (err < 0) return err;
/* Now give the external 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)
err = write_control_reg(chip, GML_CONVERTER_ENABLE | GML_48KHZ, true);
if (snd_BUG_ON(rate >= 50000 &&
chip->digital_mode == DIGITAL_MODE_ADAT)) return -EINVAL;
/* 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; return0;
}
/* Get the control register & clear the appropriate bits */
control_reg = le32_to_cpu(chip->comm_page->control_register);
control_reg &= GML_CLOCK_CLEAR_MASK & GML_SPDIF_RATE_CLEAR_MASK;
clock = 0;
switch (rate) { case96000:
clock = GML_96KHZ; break; case88200:
clock = GML_88KHZ; break; case48000:
clock = GML_48KHZ | GML_SPDIF_SAMPLE_RATE1; break; case44100:
clock = GML_44KHZ; /* Professional mode */ if (control_reg & GML_SPDIF_PRO_MODE)
clock |= GML_SPDIF_SAMPLE_RATE0; break; case32000:
clock = GML_32KHZ | GML_SPDIF_SAMPLE_RATE0 |
GML_SPDIF_SAMPLE_RATE1; break; case22050:
clock = GML_22KHZ; break; case16000:
clock = GML_16KHZ; break; case11025:
clock = GML_11KHZ; break; case8000:
clock = GML_8KHZ; break; default: /* If this is a non-standard rate, then the driver needs to
use Layla24's special "continuous frequency" mode */
clock = LAYLA24_CONTINUOUS_CLOCK; if (rate > 50000) {
base_rate = rate >> 1;
control_reg |= GML_DOUBLE_SPEED_MODE;
} else {
base_rate = rate;
}
/* Depending on what digital mode you want, Layla24 needs different ASICs loaded.ThisfunctioncheckstheASICneededforthenewmodeandsees
if it matches the one already loaded. */ staticint switch_asic(struct echoaudio *chip, short asic)
{
s8 *monitors;
/* Check to see if this is already loaded */ if (asic != chip->asic_code) {
monitors = kmemdup(chip->comm_page->monitors,
MONITOR_ARRAY_SIZE, GFP_KERNEL); if (! monitors) return -ENOMEM;
staticint dsp_set_digital_mode(struct echoaudio *chip, u8 mode)
{
u32 control_reg; int err, incompatible_clock; short asic;
/* 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;
asic = FW_LAYLA24_2S_ASIC; break; case DIGITAL_MODE_ADAT: if (chip->input_clock == ECHO_CLOCK_SPDIF)
incompatible_clock = true;
asic = FW_LAYLA24_2A_ASIC; break; default:
dev_err(chip->card->dev, "Digital mode not supported: %d\n", mode); return -EINVAL;
}
if (incompatible_clock) { /* Switch to 48KHz, internal */
chip->sample_rate = 48000;
spin_lock_irq(&chip->lock);
set_input_clock(chip, ECHO_CLOCK_INTERNAL);
spin_unlock_irq(&chip->lock);
}
/* switch_asic() can sleep */ if (switch_asic(chip, asic) < 0) return -EIO;
spin_lock_irq(&chip->lock);
/* Tweak the control register */
control_reg = le32_to_cpu(chip->comm_page->control_register);
control_reg &= GML_DIGITAL_MODE_CLEAR_MASK;
switch (mode) { case DIGITAL_MODE_SPDIF_OPTICAL:
control_reg |= GML_SPDIF_OPTICAL_MODE; break; case DIGITAL_MODE_SPDIF_RCA: /* GML_SPDIF_OPTICAL_MODE bit cleared */ break; case DIGITAL_MODE_ADAT:
control_reg |= GML_ADAT_MODE;
control_reg &= ~GML_DOUBLE_SPEED_MODE; 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.