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 set_input_clock(struct echoaudio *chip, u16 clock);
0033 static int set_professional_spdif(struct echoaudio *chip, char prof);
0034 static int update_flags(struct echoaudio *chip);
0035 static int set_vmixer_gain(struct echoaudio *chip, u16 output, u16 pipe,
0036                int gain);
0037 static int update_vmixer_level(struct echoaudio *chip);
0038 
0039 
0040 static int init_hw(struct echoaudio *chip, u16 device_id, u16 subdevice_id)
0041 {
0042     int err;
0043 
0044     if (snd_BUG_ON((subdevice_id & 0xfff0) != MIA))
0045         return -ENODEV;
0046 
0047     err = init_dsp_comm_page(chip);
0048     if (err) {
0049         dev_err(chip->card->dev,
0050             "init_hw - could not initialize DSP comm page\n");
0051         return err;
0052     }
0053 
0054     chip->device_id = device_id;
0055     chip->subdevice_id = subdevice_id;
0056     chip->bad_board = true;
0057     chip->dsp_code_to_load = FW_MIA_DSP;
0058     /* Since this card has no ASIC, mark it as loaded so everything
0059        works OK */
0060     chip->asic_loaded = true;
0061     if ((subdevice_id & 0x0000f) == MIA_MIDI_REV)
0062         chip->has_midi = true;
0063     chip->input_clock_types = ECHO_CLOCK_BIT_INTERNAL |
0064         ECHO_CLOCK_BIT_SPDIF;
0065 
0066     err = load_firmware(chip);
0067     if (err < 0)
0068         return err;
0069     chip->bad_board = false;
0070 
0071     return err;
0072 }
0073 
0074 
0075 
0076 static int set_mixer_defaults(struct echoaudio *chip)
0077 {
0078     return init_line_levels(chip);
0079 }
0080 
0081 
0082 
0083 static u32 detect_input_clocks(const struct echoaudio *chip)
0084 {
0085     u32 clocks_from_dsp, clock_bits;
0086 
0087     /* Map the DSP clock detect bits to the generic driver clock
0088        detect bits */
0089     clocks_from_dsp = le32_to_cpu(chip->comm_page->status_clocks);
0090 
0091     clock_bits = ECHO_CLOCK_BIT_INTERNAL;
0092 
0093     if (clocks_from_dsp & GLDM_CLOCK_DETECT_BIT_SPDIF)
0094         clock_bits |= ECHO_CLOCK_BIT_SPDIF;
0095 
0096     return clock_bits;
0097 }
0098 
0099 
0100 
0101 /* The Mia has no ASIC. Just do nothing */
0102 static int load_asic(struct echoaudio *chip)
0103 {
0104     return 0;
0105 }
0106 
0107 
0108 
0109 static int set_sample_rate(struct echoaudio *chip, u32 rate)
0110 {
0111     u32 control_reg;
0112 
0113     switch (rate) {
0114     case 96000:
0115         control_reg = MIA_96000;
0116         break;
0117     case 88200:
0118         control_reg = MIA_88200;
0119         break;
0120     case 48000:
0121         control_reg = MIA_48000;
0122         break;
0123     case 44100:
0124         control_reg = MIA_44100;
0125         break;
0126     case 32000:
0127         control_reg = MIA_32000;
0128         break;
0129     default:
0130         dev_err(chip->card->dev,
0131             "set_sample_rate: %d invalid!\n", rate);
0132         return -EINVAL;
0133     }
0134 
0135     /* Override the clock setting if this Mia is set to S/PDIF clock */
0136     if (chip->input_clock == ECHO_CLOCK_SPDIF)
0137         control_reg |= MIA_SPDIF;
0138 
0139     /* Set the control register if it has changed */
0140     if (control_reg != le32_to_cpu(chip->comm_page->control_register)) {
0141         if (wait_handshake(chip))
0142             return -EIO;
0143 
0144         chip->comm_page->sample_rate = cpu_to_le32(rate);   /* ignored by the DSP */
0145         chip->comm_page->control_register = cpu_to_le32(control_reg);
0146         chip->sample_rate = rate;
0147 
0148         clear_handshake(chip);
0149         return send_vector(chip, DSP_VC_UPDATE_CLOCKS);
0150     }
0151     return 0;
0152 }
0153 
0154 
0155 
0156 static int set_input_clock(struct echoaudio *chip, u16 clock)
0157 {
0158     dev_dbg(chip->card->dev, "set_input_clock(%d)\n", clock);
0159     if (snd_BUG_ON(clock != ECHO_CLOCK_INTERNAL &&
0160                clock != ECHO_CLOCK_SPDIF))
0161         return -EINVAL;
0162 
0163     chip->input_clock = clock;
0164     return set_sample_rate(chip, chip->sample_rate);
0165 }
0166 
0167 
0168 
0169 /* This function routes the sound from a virtual channel to a real output */
0170 static int set_vmixer_gain(struct echoaudio *chip, u16 output, u16 pipe,
0171                int gain)
0172 {
0173     int index;
0174 
0175     if (snd_BUG_ON(pipe >= num_pipes_out(chip) ||
0176                output >= num_busses_out(chip)))
0177         return -EINVAL;
0178 
0179     if (wait_handshake(chip))
0180         return -EIO;
0181 
0182     chip->vmixer_gain[output][pipe] = gain;
0183     index = output * num_pipes_out(chip) + pipe;
0184     chip->comm_page->vmixer[index] = gain;
0185 
0186     dev_dbg(chip->card->dev,
0187         "set_vmixer_gain: pipe %d, out %d = %d\n", pipe, output, gain);
0188     return 0;
0189 }
0190 
0191 
0192 
0193 /* Tell the DSP to read and update virtual mixer levels in comm page. */
0194 static int update_vmixer_level(struct echoaudio *chip)
0195 {
0196     if (wait_handshake(chip))
0197         return -EIO;
0198     clear_handshake(chip);
0199     return send_vector(chip, DSP_VC_SET_VMIXER_GAIN);
0200 }
0201 
0202 
0203 
0204 /* Tell the DSP to reread the flags from the comm page */
0205 static int update_flags(struct echoaudio *chip)
0206 {
0207     if (wait_handshake(chip))
0208         return -EIO;
0209     clear_handshake(chip);
0210     return send_vector(chip, DSP_VC_UPDATE_FLAGS);
0211 }
0212 
0213 
0214 
0215 static int set_professional_spdif(struct echoaudio *chip, char prof)
0216 {
0217     dev_dbg(chip->card->dev, "set_professional_spdif %d\n", prof);
0218     if (prof)
0219         chip->comm_page->flags |=
0220             cpu_to_le32(DSP_FLAG_PROFESSIONAL_SPDIF);
0221     else
0222         chip->comm_page->flags &=
0223             ~cpu_to_le32(DSP_FLAG_PROFESSIONAL_SPDIF);
0224     chip->professional_spdif = prof;
0225     return update_flags(chip);
0226 }
0227