Linux kernel & device driver programming

Cross-Referenced Linux and Device Driver Code

[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ]
Version: [ 2.6.11.8 ] [ 2.6.25 ] [ 2.6.25.8 ] [ 2.6.31.13 ] Architecture: [ i386 ]
  1 /****************************************************************************
  2 
  3    Copyright Echo Digital Audio Corporation (c) 1998 - 2004
  4    All rights reserved
  5    www.echoaudio.com
  6 
  7    This file is part of Echo Digital Audio's generic driver library.
  8 
  9    Echo Digital Audio's generic driver library is free software;
 10    you can redistribute it and/or modify it under the terms of
 11    the GNU General Public License as published by the Free Software
 12    Foundation.
 13 
 14    This program is distributed in the hope that it will be useful,
 15    but WITHOUT ANY WARRANTY; without even the implied warranty of
 16    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 17    GNU General Public License for more details.
 18 
 19    You should have received a copy of the GNU General Public License
 20    along with this program; if not, write to the Free Software
 21    Foundation, Inc., 59 Temple Place - Suite 330, Boston,
 22    MA  02111-1307, USA.
 23 
 24    *************************************************************************
 25 
 26  Translation from C++ and adaptation for use in ALSA-Driver
 27  were made by Giuliano Pochini <pochini@shiny.it>
 28 
 29 ****************************************************************************/
 30 
 31 
 32 static int read_dsp(struct echoaudio *chip, u32 *data);
 33 static int set_professional_spdif(struct echoaudio *chip, char prof);
 34 static int load_asic_generic(struct echoaudio *chip, u32 cmd,
 35                              const struct firmware *asic);
 36 static int check_asic_status(struct echoaudio *chip);
 37 static int update_flags(struct echoaudio *chip);
 38 
 39 
 40 static int init_hw(struct echoaudio *chip, u16 device_id, u16 subdevice_id)
 41 {
 42         int err;
 43 
 44         DE_INIT(("init_hw() - Layla20\n"));
 45         snd_assert((subdevice_id & 0xfff0) == LAYLA20, return -ENODEV);
 46 
 47         if ((err = init_dsp_comm_page(chip))) {
 48                 DE_INIT(("init_hw - could not initialize DSP comm page\n"));
 49                 return err;
 50         }
 51 
 52         chip->device_id = device_id;
 53         chip->subdevice_id = subdevice_id;
 54         chip->bad_board = TRUE;
 55         chip->has_midi = TRUE;
 56         chip->dsp_code_to_load = &card_fw[FW_LAYLA20_DSP];
 57         chip->input_clock_types =
 58                 ECHO_CLOCK_BIT_INTERNAL | ECHO_CLOCK_BIT_SPDIF |
 59                 ECHO_CLOCK_BIT_WORD | ECHO_CLOCK_BIT_SUPER;
 60         chip->output_clock_types =
 61                 ECHO_CLOCK_BIT_WORD | ECHO_CLOCK_BIT_SUPER;
 62 
 63         if ((err = load_firmware(chip)) < 0)
 64                 return err;
 65         chip->bad_board = FALSE;
 66 
 67         if ((err = init_line_levels(chip)) < 0)
 68                 return err;
 69 
 70         err = set_professional_spdif(chip, TRUE);
 71 
 72         DE_INIT(("init_hw done\n"));
 73         return err;
 74 }
 75 
 76 
 77 
 78 static u32 detect_input_clocks(const struct echoaudio *chip)
 79 {
 80         u32 clocks_from_dsp, clock_bits;
 81 
 82         /* Map the DSP clock detect bits to the generic driver clock detect bits */
 83         clocks_from_dsp = le32_to_cpu(chip->comm_page->status_clocks);
 84 
 85         clock_bits = ECHO_CLOCK_BIT_INTERNAL;
 86 
 87         if (clocks_from_dsp & GLDM_CLOCK_DETECT_BIT_SPDIF)
 88                 clock_bits |= ECHO_CLOCK_BIT_SPDIF;
 89 
 90         if (clocks_from_dsp & GLDM_CLOCK_DETECT_BIT_WORD) {
 91                 if (clocks_from_dsp & GLDM_CLOCK_DETECT_BIT_SUPER)
 92                         clock_bits |= ECHO_CLOCK_BIT_SUPER;
 93                 else
 94                         clock_bits |= ECHO_CLOCK_BIT_WORD;
 95         }
 96 
 97         return clock_bits;
 98 }
 99 
100 
101 
102 /* ASIC status check - some cards have one or two ASICs that need to be
103 loaded.  Once that load is complete, this function is called to see if
104 the load was successful.
105 If this load fails, it does not necessarily mean that the hardware is
106 defective - the external box may be disconnected or turned off.
107 This routine sometimes fails for Layla20; for Layla20, the loop runs
108 5 times and succeeds if it wins on three of the loops. */
109 static int check_asic_status(struct echoaudio *chip)
110 {
111         u32 asic_status;
112         int goodcnt, i;
113 
114         chip->asic_loaded = FALSE;
115         for (i = goodcnt = 0; i < 5; i++) {
116                 send_vector(chip, DSP_VC_TEST_ASIC);
117 
118                 /* The DSP will return a value to indicate whether or not
119                    the ASIC is currently loaded */
120                 if (read_dsp(chip, &asic_status) < 0) {
121                         DE_ACT(("check_asic_status: failed on read_dsp\n"));
122                         return -EIO;
123                 }
124 
125                 if (asic_status == ASIC_ALREADY_LOADED) {
126                         if (++goodcnt == 3) {
127                                 chip->asic_loaded = TRUE;
128                                 return 0;
129                         }
130                 }
131         }
132         return -EIO;
133 }
134 
135 
136 
137 /* Layla20 has an ASIC in the external box */
138 static int load_asic(struct echoaudio *chip)
139 {
140         int err;
141 
142         if (chip->asic_loaded)
143                 return 0;
144 
145         err = load_asic_generic(chip, DSP_FNC_LOAD_LAYLA_ASIC,
146                                 &card_fw[FW_LAYLA20_ASIC]);
147         if (err < 0)
148                 return err;
149 
150         /* Check if ASIC is alive and well. */
151         return check_asic_status(chip);
152 }
153 
154 
155 
156 static int set_sample_rate(struct echoaudio *chip, u32 rate)
157 {
158         snd_assert(rate >= 8000 && rate <= 50000, return -EINVAL);
159 
160         /* Only set the clock for internal mode. Do not return failure,
161            simply treat it as a non-event. */
162         if (chip->input_clock != ECHO_CLOCK_INTERNAL) {
163                 DE_ACT(("set_sample_rate: Cannot set sample rate - "
164                         "clock not set to CLK_CLOCKININTERNAL\n"));
165                 chip->comm_page->sample_rate = cpu_to_le32(rate);
166                 chip->sample_rate = rate;
167                 return 0;
168         }
169 
170         if (wait_handshake(chip))
171                 return -EIO;
172 
173         DE_ACT(("set_sample_rate(%d)\n", rate));
174         chip->sample_rate = rate;
175         chip->comm_page->sample_rate = cpu_to_le32(rate);
176         clear_handshake(chip);
177         return send_vector(chip, DSP_VC_SET_LAYLA_SAMPLE_RATE);
178 }
179 
180 
181 
182 static int set_input_clock(struct echoaudio *chip, u16 clock_source)
183 {
184         u16 clock;
185         u32 rate;
186 
187         DE_ACT(("set_input_clock:\n"));
188         rate = 0;
189         switch (clock_source) {
190         case ECHO_CLOCK_INTERNAL:
191                 DE_ACT(("Set Layla20 clock to INTERNAL\n"));
192                 rate = chip->sample_rate;
193                 clock = LAYLA20_CLOCK_INTERNAL;
194                 break;
195         case ECHO_CLOCK_SPDIF:
196                 DE_ACT(("Set Layla20 clock to SPDIF\n"));
197                 clock = LAYLA20_CLOCK_SPDIF;
198                 break;
199         case ECHO_CLOCK_WORD:
200                 DE_ACT(("Set Layla20 clock to WORD\n"));
201                 clock = LAYLA20_CLOCK_WORD;
202                 break;
203         case ECHO_CLOCK_SUPER:
204                 DE_ACT(("Set Layla20 clock to SUPER\n"));
205                 clock = LAYLA20_CLOCK_SUPER;
206                 break;
207         default:
208                 DE_ACT(("Input clock 0x%x not supported for Layla24\n",
209                         clock_source));
210                 return -EINVAL;
211         }
212         chip->input_clock = clock_source;
213 
214         chip->comm_page->input_clock = cpu_to_le16(clock);
215         clear_handshake(chip);
216         send_vector(chip, DSP_VC_UPDATE_CLOCKS);
217 
218         if (rate)
219                 set_sample_rate(chip, rate);
220 
221         return 0;
222 }
223 
224 
225 
226 static int set_output_clock(struct echoaudio *chip, u16 clock)
227 {
228         DE_ACT(("set_output_clock: %d\n", clock));
229         switch (clock) {
230         case ECHO_CLOCK_SUPER:
231                 clock = LAYLA20_OUTPUT_CLOCK_SUPER;
232                 break;
233         case ECHO_CLOCK_WORD:
234                 clock = LAYLA20_OUTPUT_CLOCK_WORD;
235                 break;
236         default:
237                 DE_ACT(("set_output_clock wrong clock\n"));
238                 return -EINVAL;
239         }
240 
241         if (wait_handshake(chip))
242                 return -EIO;
243 
244         chip->comm_page->output_clock = cpu_to_le16(clock);
245         chip->output_clock = clock;
246         clear_handshake(chip);
247         return send_vector(chip, DSP_VC_UPDATE_CLOCKS);
248 }
249 
250 
251 
252 /* Set input bus gain (one unit is 0.5dB !) */
253 static int set_input_gain(struct echoaudio *chip, u16 input, int gain)
254 {
255         snd_assert(input < num_busses_in(chip), return -EINVAL);
256 
257         if (wait_handshake(chip))
258                 return -EIO;
259 
260         chip->input_gain[input] = gain;
261         gain += GL20_INPUT_GAIN_MAGIC_NUMBER;
262         chip->comm_page->line_in_level[input] = gain;
263         return 0;
264 }
265 
266 
267 
268 /* Tell the DSP to reread the flags from the comm page */
269 static int update_flags(struct echoaudio *chip)
270 {
271         if (wait_handshake(chip))
272                 return -EIO;
273         clear_handshake(chip);
274         return send_vector(chip, DSP_VC_UPDATE_FLAGS);
275 }
276 
277 
278 
279 static int set_professional_spdif(struct echoaudio *chip, char prof)
280 {
281         DE_ACT(("set_professional_spdif %d\n", prof));
282         if (prof)
283                 chip->comm_page->flags |=
284                         __constant_cpu_to_le32(DSP_FLAG_PROFESSIONAL_SPDIF);
285         else
286                 chip->comm_page->flags &=
287                         ~__constant_cpu_to_le32(DSP_FLAG_PROFESSIONAL_SPDIF);
288         chip->professional_spdif = prof;
289         return update_flags(chip);
290 }
291 
  This page was automatically generated by the LXR engine.