Back to home page

OSCL-LXR

 
 

    


0001 /****************************************************************************
0002 
0003    Copyright Echo Digital Audio Corporation (c) 1998 - 2004
0004    All rights reserved
0005    www.echoaudio.com
0006 
0007    This file is part of Echo Digital Audio's generic driver library.
0008 
0009    Echo Digital Audio's generic driver library is free software;
0010    you can redistribute it and/or modify it under the terms of
0011    the GNU General Public License as published by the Free Software
0012    Foundation.
0013 
0014    This program is distributed in the hope that it will be useful,
0015    but WITHOUT ANY WARRANTY; without even the implied warranty of
0016    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
0017    GNU General Public License for more details.
0018 
0019    You should have received a copy of the GNU General Public License
0020    along with this program; if not, write to the Free Software
0021    Foundation, Inc., 59 Temple Place - Suite 330, Boston,
0022    MA  02111-1307, USA.
0023 
0024    *************************************************************************
0025 
0026  Translation from C++ and adaptation for use in ALSA-Driver
0027  were made by Giuliano Pochini <pochini@shiny.it>
0028 
0029 ****************************************************************************/
0030 
0031 
0032 static int read_dsp(struct echoaudio *chip, u32 *data);
0033 static int set_professional_spdif(struct echoaudio *chip, char prof);
0034 static int load_asic_generic(struct echoaudio *chip, u32 cmd, short asic);
0035 static int check_asic_status(struct echoaudio *chip);
0036 static int update_flags(struct echoaudio *chip);
0037 
0038 
0039 static int init_hw(struct echoaudio *chip, u16 device_id, u16 subdevice_id)
0040 {
0041     int err;
0042 
0043     if (snd_BUG_ON((subdevice_id & 0xfff0) != LAYLA20))
0044         return -ENODEV;
0045 
0046     err = init_dsp_comm_page(chip);
0047     if (err) {
0048         dev_err(chip->card->dev,
0049             "init_hw - could not initialize DSP comm page\n");
0050         return err;
0051     }
0052 
0053     chip->device_id = device_id;
0054     chip->subdevice_id = subdevice_id;
0055     chip->bad_board = true;
0056     chip->has_midi = true;
0057     chip->dsp_code_to_load = FW_LAYLA20_DSP;
0058     chip->input_clock_types =
0059         ECHO_CLOCK_BIT_INTERNAL | ECHO_CLOCK_BIT_SPDIF |
0060         ECHO_CLOCK_BIT_WORD | ECHO_CLOCK_BIT_SUPER;
0061     chip->output_clock_types =
0062         ECHO_CLOCK_BIT_WORD | ECHO_CLOCK_BIT_SUPER;
0063 
0064     err = load_firmware(chip);
0065     if (err < 0)
0066         return err;
0067     chip->bad_board = false;
0068 
0069     return err;
0070 }
0071 
0072 
0073 
0074 static int set_mixer_defaults(struct echoaudio *chip)
0075 {
0076     chip->professional_spdif = false;
0077     return init_line_levels(chip);
0078 }
0079 
0080 
0081 
0082 static u32 detect_input_clocks(const struct echoaudio *chip)
0083 {
0084     u32 clocks_from_dsp, clock_bits;
0085 
0086     /* Map the DSP clock detect bits to the generic driver clock detect bits */
0087     clocks_from_dsp = le32_to_cpu(chip->comm_page->status_clocks);
0088 
0089     clock_bits = ECHO_CLOCK_BIT_INTERNAL;
0090 
0091     if (clocks_from_dsp & GLDM_CLOCK_DETECT_BIT_SPDIF)
0092         clock_bits |= ECHO_CLOCK_BIT_SPDIF;
0093 
0094     if (clocks_from_dsp & GLDM_CLOCK_DETECT_BIT_WORD) {
0095         if (clocks_from_dsp & GLDM_CLOCK_DETECT_BIT_SUPER)
0096             clock_bits |= ECHO_CLOCK_BIT_SUPER;
0097         else
0098             clock_bits |= ECHO_CLOCK_BIT_WORD;
0099     }
0100 
0101     return clock_bits;
0102 }
0103 
0104 
0105 
0106 /* ASIC status check - some cards have one or two ASICs that need to be
0107 loaded.  Once that load is complete, this function is called to see if
0108 the load was successful.
0109 If this load fails, it does not necessarily mean that the hardware is
0110 defective - the external box may be disconnected or turned off.
0111 This routine sometimes fails for Layla20; for Layla20, the loop runs
0112 5 times and succeeds if it wins on three of the loops. */
0113 static int check_asic_status(struct echoaudio *chip)
0114 {
0115     u32 asic_status;
0116     int goodcnt, i;
0117 
0118     chip->asic_loaded = false;
0119     for (i = goodcnt = 0; i < 5; i++) {
0120         send_vector(chip, DSP_VC_TEST_ASIC);
0121 
0122         /* The DSP will return a value to indicate whether or not
0123            the ASIC is currently loaded */
0124         if (read_dsp(chip, &asic_status) < 0) {
0125             dev_err(chip->card->dev,
0126                 "check_asic_status: failed on read_dsp\n");
0127             return -EIO;
0128         }
0129 
0130         if (asic_status == ASIC_ALREADY_LOADED) {
0131             if (++goodcnt == 3) {
0132                 chip->asic_loaded = true;
0133                 return 0;
0134             }
0135         }
0136     }
0137     return -EIO;
0138 }
0139 
0140 
0141 
0142 /* Layla20 has an ASIC in the external box */
0143 static int load_asic(struct echoaudio *chip)
0144 {
0145     int err;
0146 
0147     if (chip->asic_loaded)
0148         return 0;
0149 
0150     err = load_asic_generic(chip, DSP_FNC_LOAD_LAYLA_ASIC,
0151                 FW_LAYLA20_ASIC);
0152     if (err < 0)
0153         return err;
0154 
0155     /* Check if ASIC is alive and well. */
0156     return check_asic_status(chip);
0157 }
0158 
0159 
0160 
0161 static int set_sample_rate(struct echoaudio *chip, u32 rate)
0162 {
0163     if (snd_BUG_ON(rate < 8000 || rate > 50000))
0164         return -EINVAL;
0165 
0166     /* Only set the clock for internal mode. Do not return failure,
0167        simply treat it as a non-event. */
0168     if (chip->input_clock != ECHO_CLOCK_INTERNAL) {
0169         dev_warn(chip->card->dev,
0170              "Cannot set sample rate - clock not set to CLK_CLOCKININTERNAL\n");
0171         chip->comm_page->sample_rate = cpu_to_le32(rate);
0172         chip->sample_rate = rate;
0173         return 0;
0174     }
0175 
0176     if (wait_handshake(chip))
0177         return -EIO;
0178 
0179     dev_dbg(chip->card->dev, "set_sample_rate(%d)\n", rate);
0180     chip->sample_rate = rate;
0181     chip->comm_page->sample_rate = cpu_to_le32(rate);
0182     clear_handshake(chip);
0183     return send_vector(chip, DSP_VC_SET_LAYLA_SAMPLE_RATE);
0184 }
0185 
0186 
0187 
0188 static int set_input_clock(struct echoaudio *chip, u16 clock_source)
0189 {
0190     u16 clock;
0191     u32 rate;
0192 
0193     rate = 0;
0194     switch (clock_source) {
0195     case ECHO_CLOCK_INTERNAL:
0196         rate = chip->sample_rate;
0197         clock = LAYLA20_CLOCK_INTERNAL;
0198         break;
0199     case ECHO_CLOCK_SPDIF:
0200         clock = LAYLA20_CLOCK_SPDIF;
0201         break;
0202     case ECHO_CLOCK_WORD:
0203         clock = LAYLA20_CLOCK_WORD;
0204         break;
0205     case ECHO_CLOCK_SUPER:
0206         clock = LAYLA20_CLOCK_SUPER;
0207         break;
0208     default:
0209         dev_err(chip->card->dev,
0210             "Input clock 0x%x not supported for Layla24\n",
0211             clock_source);
0212         return -EINVAL;
0213     }
0214     chip->input_clock = clock_source;
0215 
0216     chip->comm_page->input_clock = cpu_to_le16(clock);
0217     clear_handshake(chip);
0218     send_vector(chip, DSP_VC_UPDATE_CLOCKS);
0219 
0220     if (rate)
0221         set_sample_rate(chip, rate);
0222 
0223     return 0;
0224 }
0225 
0226 
0227 
0228 static int set_output_clock(struct echoaudio *chip, u16 clock)
0229 {
0230     switch (clock) {
0231     case ECHO_CLOCK_SUPER:
0232         clock = LAYLA20_OUTPUT_CLOCK_SUPER;
0233         break;
0234     case ECHO_CLOCK_WORD:
0235         clock = LAYLA20_OUTPUT_CLOCK_WORD;
0236         break;
0237     default:
0238         dev_err(chip->card->dev, "set_output_clock wrong clock\n");
0239         return -EINVAL;
0240     }
0241 
0242     if (wait_handshake(chip))
0243         return -EIO;
0244 
0245     chip->comm_page->output_clock = cpu_to_le16(clock);
0246     chip->output_clock = clock;
0247     clear_handshake(chip);
0248     return send_vector(chip, DSP_VC_UPDATE_CLOCKS);
0249 }
0250 
0251 
0252 
0253 /* Set input bus gain (one unit is 0.5dB !) */
0254 static int set_input_gain(struct echoaudio *chip, u16 input, int gain)
0255 {
0256     if (snd_BUG_ON(input >= num_busses_in(chip)))
0257         return -EINVAL;
0258 
0259     if (wait_handshake(chip))
0260         return -EIO;
0261 
0262     chip->input_gain[input] = gain;
0263     gain += GL20_INPUT_GAIN_MAGIC_NUMBER;
0264     chip->comm_page->line_in_level[input] = gain;
0265     return 0;
0266 }
0267 
0268 
0269 
0270 /* Tell the DSP to reread the flags from the comm page */
0271 static int update_flags(struct echoaudio *chip)
0272 {
0273     if (wait_handshake(chip))
0274         return -EIO;
0275     clear_handshake(chip);
0276     return send_vector(chip, DSP_VC_UPDATE_FLAGS);
0277 }
0278 
0279 
0280 
0281 static int set_professional_spdif(struct echoaudio *chip, char prof)
0282 {
0283     if (prof)
0284         chip->comm_page->flags |=
0285             cpu_to_le32(DSP_FLAG_PROFESSIONAL_SPDIF);
0286     else
0287         chip->comm_page->flags &=
0288             ~cpu_to_le32(DSP_FLAG_PROFESSIONAL_SPDIF);
0289     chip->professional_spdif = prof;
0290     return update_flags(chip);
0291 }