Path: blob/master/sound/pci/echoaudio/echoaudio_3g.c
10818 views
/****************************************************************************12Copyright Echo Digital Audio Corporation (c) 1998 - 20043All rights reserved4www.echoaudio.com56This file is part of Echo Digital Audio's generic driver library.78Echo Digital Audio's generic driver library is free software;9you can redistribute it and/or modify it under the terms of10the GNU General Public License as published by the Free Software11Foundation.1213This program is distributed in the hope that it will be useful,14but WITHOUT ANY WARRANTY; without even the implied warranty of15MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the16GNU General Public License for more details.1718You should have received a copy of the GNU General Public License19along with this program; if not, write to the Free Software20Foundation, Inc., 59 Temple Place - Suite 330, Boston,21MA 02111-1307, USA.2223*************************************************************************2425Translation from C++ and adaptation for use in ALSA-Driver26were made by Giuliano Pochini <[email protected]>2728****************************************************************************/29303132/* These functions are common for all "3G" cards */333435static int check_asic_status(struct echoaudio *chip)36{37u32 box_status;3839if (wait_handshake(chip))40return -EIO;4142chip->comm_page->ext_box_status = cpu_to_le32(E3G_ASIC_NOT_LOADED);43chip->asic_loaded = FALSE;44clear_handshake(chip);45send_vector(chip, DSP_VC_TEST_ASIC);4647if (wait_handshake(chip)) {48chip->dsp_code = NULL;49return -EIO;50}5152box_status = le32_to_cpu(chip->comm_page->ext_box_status);53DE_INIT(("box_status=%x\n", box_status));54if (box_status == E3G_ASIC_NOT_LOADED)55return -ENODEV;5657chip->asic_loaded = TRUE;58return box_status & E3G_BOX_TYPE_MASK;59}60616263static inline u32 get_frq_reg(struct echoaudio *chip)64{65return le32_to_cpu(chip->comm_page->e3g_frq_register);66}67686970/* Most configuration of 3G cards is accomplished by writing the control71register. write_control_reg sends the new control register value to the DSP. */72static int write_control_reg(struct echoaudio *chip, u32 ctl, u32 frq,73char force)74{75if (wait_handshake(chip))76return -EIO;7778DE_ACT(("WriteControlReg: Setting 0x%x, 0x%x\n", ctl, frq));7980ctl = cpu_to_le32(ctl);81frq = cpu_to_le32(frq);8283if (ctl != chip->comm_page->control_register ||84frq != chip->comm_page->e3g_frq_register || force) {85chip->comm_page->e3g_frq_register = frq;86chip->comm_page->control_register = ctl;87clear_handshake(chip);88return send_vector(chip, DSP_VC_WRITE_CONTROL_REG);89}9091DE_ACT(("WriteControlReg: not written, no change\n"));92return 0;93}94959697/* Set the digital mode - currently for Gina24, Layla24, Mona, 3G */98static int set_digital_mode(struct echoaudio *chip, u8 mode)99{100u8 previous_mode;101int err, i, o;102103/* All audio channels must be closed before changing the digital mode */104if (snd_BUG_ON(chip->pipe_alloc_mask))105return -EAGAIN;106107if (snd_BUG_ON(!(chip->digital_modes & (1 << mode))))108return -EINVAL;109110previous_mode = chip->digital_mode;111err = dsp_set_digital_mode(chip, mode);112113/* If we successfully changed the digital mode from or to ADAT,114* then make sure all output, input and monitor levels are115* updated by the DSP comm object. */116if (err >= 0 && previous_mode != mode &&117(previous_mode == DIGITAL_MODE_ADAT || mode == DIGITAL_MODE_ADAT)) {118spin_lock_irq(&chip->lock);119for (o = 0; o < num_busses_out(chip); o++)120for (i = 0; i < num_busses_in(chip); i++)121set_monitor_gain(chip, o, i,122chip->monitor_gain[o][i]);123124#ifdef ECHOCARD_HAS_INPUT_GAIN125for (i = 0; i < num_busses_in(chip); i++)126set_input_gain(chip, i, chip->input_gain[i]);127update_input_line_level(chip);128#endif129130for (o = 0; o < num_busses_out(chip); o++)131set_output_gain(chip, o, chip->output_gain[o]);132update_output_line_level(chip);133spin_unlock_irq(&chip->lock);134}135136return err;137}138139140141static u32 set_spdif_bits(struct echoaudio *chip, u32 control_reg, u32 rate)142{143control_reg &= E3G_SPDIF_FORMAT_CLEAR_MASK;144145switch (rate) {146case 32000 :147control_reg |= E3G_SPDIF_SAMPLE_RATE0 | E3G_SPDIF_SAMPLE_RATE1;148break;149case 44100 :150if (chip->professional_spdif)151control_reg |= E3G_SPDIF_SAMPLE_RATE0;152break;153case 48000 :154control_reg |= E3G_SPDIF_SAMPLE_RATE1;155break;156}157158if (chip->professional_spdif)159control_reg |= E3G_SPDIF_PRO_MODE;160161if (chip->non_audio_spdif)162control_reg |= E3G_SPDIF_NOT_AUDIO;163164control_reg |= E3G_SPDIF_24_BIT | E3G_SPDIF_TWO_CHANNEL |165E3G_SPDIF_COPY_PERMIT;166167return control_reg;168}169170171172/* Set the S/PDIF output format */173static int set_professional_spdif(struct echoaudio *chip, char prof)174{175u32 control_reg;176177control_reg = le32_to_cpu(chip->comm_page->control_register);178chip->professional_spdif = prof;179control_reg = set_spdif_bits(chip, control_reg, chip->sample_rate);180return write_control_reg(chip, control_reg, get_frq_reg(chip), 0);181}182183184185/* detect_input_clocks() returns a bitmask consisting of all the input clocks186currently connected to the hardware; this changes as the user connects and187disconnects clock inputs. You should use this information to determine which188clocks the user is allowed to select. */189static u32 detect_input_clocks(const struct echoaudio *chip)190{191u32 clocks_from_dsp, clock_bits;192193/* Map the DSP clock detect bits to the generic driver clock194* detect bits */195clocks_from_dsp = le32_to_cpu(chip->comm_page->status_clocks);196197clock_bits = ECHO_CLOCK_BIT_INTERNAL;198199if (clocks_from_dsp & E3G_CLOCK_DETECT_BIT_WORD)200clock_bits |= ECHO_CLOCK_BIT_WORD;201202switch(chip->digital_mode) {203case DIGITAL_MODE_SPDIF_RCA:204case DIGITAL_MODE_SPDIF_OPTICAL:205if (clocks_from_dsp & E3G_CLOCK_DETECT_BIT_SPDIF)206clock_bits |= ECHO_CLOCK_BIT_SPDIF;207break;208case DIGITAL_MODE_ADAT:209if (clocks_from_dsp & E3G_CLOCK_DETECT_BIT_ADAT)210clock_bits |= ECHO_CLOCK_BIT_ADAT;211break;212}213214return clock_bits;215}216217218219static int load_asic(struct echoaudio *chip)220{221int box_type, err;222223if (chip->asic_loaded)224return 0;225226/* Give the DSP a few milliseconds to settle down */227mdelay(2);228229err = load_asic_generic(chip, DSP_FNC_LOAD_3G_ASIC, FW_3G_ASIC);230if (err < 0)231return err;232233chip->asic_code = FW_3G_ASIC;234235/* Now give the new ASIC some time to set up */236msleep(1000);237/* See if it worked */238box_type = check_asic_status(chip);239240/* Set up the control register if the load succeeded -241* 48 kHz, internal clock, S/PDIF RCA mode */242if (box_type >= 0) {243err = write_control_reg(chip, E3G_48KHZ,244E3G_FREQ_REG_DEFAULT, TRUE);245if (err < 0)246return err;247}248249return box_type;250}251252253254static int set_sample_rate(struct echoaudio *chip, u32 rate)255{256u32 control_reg, clock, base_rate, frq_reg;257258/* Only set the clock for internal mode. */259if (chip->input_clock != ECHO_CLOCK_INTERNAL) {260DE_ACT(("set_sample_rate: Cannot set sample rate - "261"clock not set to CLK_CLOCKININTERNAL\n"));262/* Save the rate anyhow */263chip->comm_page->sample_rate = cpu_to_le32(rate);264chip->sample_rate = rate;265set_input_clock(chip, chip->input_clock);266return 0;267}268269if (snd_BUG_ON(rate >= 50000 &&270chip->digital_mode == DIGITAL_MODE_ADAT))271return -EINVAL;272273clock = 0;274control_reg = le32_to_cpu(chip->comm_page->control_register);275control_reg &= E3G_CLOCK_CLEAR_MASK;276277switch (rate) {278case 96000:279clock = E3G_96KHZ;280break;281case 88200:282clock = E3G_88KHZ;283break;284case 48000:285clock = E3G_48KHZ;286break;287case 44100:288clock = E3G_44KHZ;289break;290case 32000:291clock = E3G_32KHZ;292break;293default:294clock = E3G_CONTINUOUS_CLOCK;295if (rate > 50000)296clock |= E3G_DOUBLE_SPEED_MODE;297break;298}299300control_reg |= clock;301control_reg = set_spdif_bits(chip, control_reg, rate);302303base_rate = rate;304if (base_rate > 50000)305base_rate /= 2;306if (base_rate < 32000)307base_rate = 32000;308309frq_reg = E3G_MAGIC_NUMBER / base_rate - 2;310if (frq_reg > E3G_FREQ_REG_MAX)311frq_reg = E3G_FREQ_REG_MAX;312313chip->comm_page->sample_rate = cpu_to_le32(rate); /* ignored by the DSP */314chip->sample_rate = rate;315DE_ACT(("SetSampleRate: %d clock %x\n", rate, control_reg));316317/* Tell the DSP about it - DSP reads both control reg & freq reg */318return write_control_reg(chip, control_reg, frq_reg, 0);319}320321322323/* Set the sample clock source to internal, S/PDIF, ADAT */324static int set_input_clock(struct echoaudio *chip, u16 clock)325{326u32 control_reg, clocks_from_dsp;327328DE_ACT(("set_input_clock:\n"));329330/* Mask off the clock select bits */331control_reg = le32_to_cpu(chip->comm_page->control_register) &332E3G_CLOCK_CLEAR_MASK;333clocks_from_dsp = le32_to_cpu(chip->comm_page->status_clocks);334335switch (clock) {336case ECHO_CLOCK_INTERNAL:337DE_ACT(("Set Echo3G clock to INTERNAL\n"));338chip->input_clock = ECHO_CLOCK_INTERNAL;339return set_sample_rate(chip, chip->sample_rate);340case ECHO_CLOCK_SPDIF:341if (chip->digital_mode == DIGITAL_MODE_ADAT)342return -EAGAIN;343DE_ACT(("Set Echo3G clock to SPDIF\n"));344control_reg |= E3G_SPDIF_CLOCK;345if (clocks_from_dsp & E3G_CLOCK_DETECT_BIT_SPDIF96)346control_reg |= E3G_DOUBLE_SPEED_MODE;347else348control_reg &= ~E3G_DOUBLE_SPEED_MODE;349break;350case ECHO_CLOCK_ADAT:351if (chip->digital_mode != DIGITAL_MODE_ADAT)352return -EAGAIN;353DE_ACT(("Set Echo3G clock to ADAT\n"));354control_reg |= E3G_ADAT_CLOCK;355control_reg &= ~E3G_DOUBLE_SPEED_MODE;356break;357case ECHO_CLOCK_WORD:358DE_ACT(("Set Echo3G clock to WORD\n"));359control_reg |= E3G_WORD_CLOCK;360if (clocks_from_dsp & E3G_CLOCK_DETECT_BIT_WORD96)361control_reg |= E3G_DOUBLE_SPEED_MODE;362else363control_reg &= ~E3G_DOUBLE_SPEED_MODE;364break;365default:366DE_ACT(("Input clock 0x%x not supported for Echo3G\n", clock));367return -EINVAL;368}369370chip->input_clock = clock;371return write_control_reg(chip, control_reg, get_frq_reg(chip), 1);372}373374375376static int dsp_set_digital_mode(struct echoaudio *chip, u8 mode)377{378u32 control_reg;379int err, incompatible_clock;380381/* Set clock to "internal" if it's not compatible with the new mode */382incompatible_clock = FALSE;383switch (mode) {384case DIGITAL_MODE_SPDIF_OPTICAL:385case DIGITAL_MODE_SPDIF_RCA:386if (chip->input_clock == ECHO_CLOCK_ADAT)387incompatible_clock = TRUE;388break;389case DIGITAL_MODE_ADAT:390if (chip->input_clock == ECHO_CLOCK_SPDIF)391incompatible_clock = TRUE;392break;393default:394DE_ACT(("Digital mode not supported: %d\n", mode));395return -EINVAL;396}397398spin_lock_irq(&chip->lock);399400if (incompatible_clock) {401chip->sample_rate = 48000;402set_input_clock(chip, ECHO_CLOCK_INTERNAL);403}404405/* Clear the current digital mode */406control_reg = le32_to_cpu(chip->comm_page->control_register);407control_reg &= E3G_DIGITAL_MODE_CLEAR_MASK;408409/* Tweak the control reg */410switch (mode) {411case DIGITAL_MODE_SPDIF_OPTICAL:412control_reg |= E3G_SPDIF_OPTICAL_MODE;413break;414case DIGITAL_MODE_SPDIF_RCA:415/* E3G_SPDIF_OPTICAL_MODE bit cleared */416break;417case DIGITAL_MODE_ADAT:418control_reg |= E3G_ADAT_MODE;419control_reg &= ~E3G_DOUBLE_SPEED_MODE; /* @@ useless */420break;421}422423err = write_control_reg(chip, control_reg, get_frq_reg(chip), 1);424spin_unlock_irq(&chip->lock);425if (err < 0)426return err;427chip->digital_mode = mode;428429DE_ACT(("set_digital_mode(%d)\n", chip->digital_mode));430return incompatible_clock;431}432433434