aboutsummaryrefslogtreecommitdiffstats
path: root/sound/pci/echoaudio/mona_dsp.c
diff options
context:
space:
mode:
Diffstat (limited to 'sound/pci/echoaudio/mona_dsp.c')
-rw-r--r--sound/pci/echoaudio/mona_dsp.c428
1 files changed, 428 insertions, 0 deletions
diff --git a/sound/pci/echoaudio/mona_dsp.c b/sound/pci/echoaudio/mona_dsp.c
new file mode 100644
index 000000000000..c0b4bf0be7d1
--- /dev/null
+++ b/sound/pci/echoaudio/mona_dsp.c
@@ -0,0 +1,428 @@
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
32static int write_control_reg(struct echoaudio *chip, u32 value, char force);
33static int set_input_clock(struct echoaudio *chip, u16 clock);
34static int set_professional_spdif(struct echoaudio *chip, char prof);
35static int set_digital_mode(struct echoaudio *chip, u8 mode);
36static int load_asic_generic(struct echoaudio *chip, u32 cmd,
37 const struct firmware *asic);
38static int check_asic_status(struct echoaudio *chip);
39
40
41static int init_hw(struct echoaudio *chip, u16 device_id, u16 subdevice_id)
42{
43 int err;
44
45 DE_INIT(("init_hw() - Mona\n"));
46 snd_assert((subdevice_id & 0xfff0) == MONA, return -ENODEV);
47
48 if ((err = init_dsp_comm_page(chip))) {
49 DE_INIT(("init_hw - could not initialize DSP comm page\n"));
50 return err;
51 }
52
53 chip->device_id = device_id;
54 chip->subdevice_id = subdevice_id;
55 chip->bad_board = TRUE;
56 chip->input_clock_types =
57 ECHO_CLOCK_BIT_INTERNAL | ECHO_CLOCK_BIT_SPDIF |
58 ECHO_CLOCK_BIT_WORD | ECHO_CLOCK_BIT_ADAT;
59 chip->digital_modes =
60 ECHOCAPS_HAS_DIGITAL_MODE_SPDIF_RCA |
61 ECHOCAPS_HAS_DIGITAL_MODE_SPDIF_OPTICAL |
62 ECHOCAPS_HAS_DIGITAL_MODE_ADAT;
63
64 /* Mona comes in both '301 and '361 flavors */
65 if (chip->device_id == DEVICE_ID_56361)
66 chip->dsp_code_to_load = &card_fw[FW_MONA_361_DSP];
67 else
68 chip->dsp_code_to_load = &card_fw[FW_MONA_301_DSP];
69
70 chip->digital_mode = DIGITAL_MODE_SPDIF_RCA;
71 chip->professional_spdif = FALSE;
72 chip->digital_in_automute = TRUE;
73
74 if ((err = load_firmware(chip)) < 0)
75 return err;
76 chip->bad_board = FALSE;
77
78 if ((err = init_line_levels(chip)) < 0)
79 return err;
80
81 err = set_digital_mode(chip, DIGITAL_MODE_SPDIF_RCA);
82 snd_assert(err >= 0, return err);
83 err = set_professional_spdif(chip, TRUE);
84
85 DE_INIT(("init_hw done\n"));
86 return err;
87}
88
89
90
91static u32 detect_input_clocks(const struct echoaudio *chip)
92{
93 u32 clocks_from_dsp, clock_bits;
94
95 /* Map the DSP clock detect bits to the generic driver clock
96 detect bits */
97 clocks_from_dsp = le32_to_cpu(chip->comm_page->status_clocks);
98
99 clock_bits = ECHO_CLOCK_BIT_INTERNAL;
100
101 if (clocks_from_dsp & GML_CLOCK_DETECT_BIT_SPDIF)
102 clock_bits |= ECHO_CLOCK_BIT_SPDIF;
103
104 if (clocks_from_dsp & GML_CLOCK_DETECT_BIT_ADAT)
105 clock_bits |= ECHO_CLOCK_BIT_ADAT;
106
107 if (clocks_from_dsp & GML_CLOCK_DETECT_BIT_WORD)
108 clock_bits |= ECHO_CLOCK_BIT_WORD;
109
110 return clock_bits;
111}
112
113
114
115/* Mona has an ASIC on the PCI card and another ASIC in the external box;
116both need to be loaded. */
117static int load_asic(struct echoaudio *chip)
118{
119 u32 control_reg;
120 int err;
121 const struct firmware *asic;
122
123 if (chip->asic_loaded)
124 return 0;
125
126 mdelay(10);
127
128 if (chip->device_id == DEVICE_ID_56361)
129 asic = &card_fw[FW_MONA_361_1_ASIC48];
130 else
131 asic = &card_fw[FW_MONA_301_1_ASIC48];
132
133 err = load_asic_generic(chip, DSP_FNC_LOAD_MONA_PCI_CARD_ASIC, asic);
134 if (err < 0)
135 return err;
136
137 chip->asic_code = asic;
138 mdelay(10);
139
140 /* Do the external one */
141 err = load_asic_generic(chip, DSP_FNC_LOAD_MONA_EXTERNAL_ASIC,
142 &card_fw[FW_MONA_2_ASIC]);
143 if (err < 0)
144 return err;
145
146 mdelay(10);
147 err = check_asic_status(chip);
148
149 /* Set up the control register if the load succeeded -
150 48 kHz, internal clock, S/PDIF RCA mode */
151 if (!err) {
152 control_reg = GML_CONVERTER_ENABLE | GML_48KHZ;
153 err = write_control_reg(chip, control_reg, TRUE);
154 }
155
156 return err;
157}
158
159
160
161/* Depending on what digital mode you want, Mona needs different ASICs
162loaded. This function checks the ASIC needed for the new mode and sees
163if it matches the one already loaded. */
164static int switch_asic(struct echoaudio *chip, char double_speed)
165{
166 const struct firmware *asic;
167 int err;
168
169 /* Check the clock detect bits to see if this is
170 a single-speed clock or a double-speed clock; load
171 a new ASIC if necessary. */
172 if (chip->device_id == DEVICE_ID_56361) {
173 if (double_speed)
174 asic = &card_fw[FW_MONA_361_1_ASIC96];
175 else
176 asic = &card_fw[FW_MONA_361_1_ASIC48];
177 } else {
178 if (double_speed)
179 asic = &card_fw[FW_MONA_301_1_ASIC96];
180 else
181 asic = &card_fw[FW_MONA_301_1_ASIC48];
182 }
183
184 if (asic != chip->asic_code) {
185 /* Load the desired ASIC */
186 err = load_asic_generic(chip, DSP_FNC_LOAD_MONA_PCI_CARD_ASIC,
187 asic);
188 if (err < 0)
189 return err;
190 chip->asic_code = asic;
191 }
192
193 return 0;
194}
195
196
197
198static int set_sample_rate(struct echoaudio *chip, u32 rate)
199{
200 u32 control_reg, clock;
201 const struct firmware *asic;
202 char force_write;
203
204 /* Only set the clock for internal mode. */
205 if (chip->input_clock != ECHO_CLOCK_INTERNAL) {
206 DE_ACT(("set_sample_rate: Cannot set sample rate - "
207 "clock not set to CLK_CLOCKININTERNAL\n"));
208 /* Save the rate anyhow */
209 chip->comm_page->sample_rate = cpu_to_le32(rate);
210 chip->sample_rate = rate;
211 return 0;
212 }
213
214 /* Now, check to see if the required ASIC is loaded */
215 if (rate >= 88200) {
216 if (chip->digital_mode == DIGITAL_MODE_ADAT)
217 return -EINVAL;
218 if (chip->device_id == DEVICE_ID_56361)
219 asic = &card_fw[FW_MONA_361_1_ASIC96];
220 else
221 asic = &card_fw[FW_MONA_301_1_ASIC96];
222 } else {
223 if (chip->device_id == DEVICE_ID_56361)
224 asic = &card_fw[FW_MONA_361_1_ASIC48];
225 else
226 asic = &card_fw[FW_MONA_301_1_ASIC48];
227 }
228
229 force_write = 0;
230 if (asic != chip->asic_code) {
231 int err;
232 /* Load the desired ASIC (load_asic_generic() can sleep) */
233 spin_unlock_irq(&chip->lock);
234 err = load_asic_generic(chip, DSP_FNC_LOAD_MONA_PCI_CARD_ASIC,
235 asic);
236 spin_lock_irq(&chip->lock);
237
238 if (err < 0)
239 return err;
240 chip->asic_code = asic;
241 force_write = 1;
242 }
243
244 /* Compute the new control register value */
245 clock = 0;
246 control_reg = le32_to_cpu(chip->comm_page->control_register);
247 control_reg &= GML_CLOCK_CLEAR_MASK;
248 control_reg &= GML_SPDIF_RATE_CLEAR_MASK;
249
250 switch (rate) {
251 case 96000:
252 clock = GML_96KHZ;
253 break;
254 case 88200:
255 clock = GML_88KHZ;
256 break;
257 case 48000:
258 clock = GML_48KHZ | GML_SPDIF_SAMPLE_RATE1;
259 break;
260 case 44100:
261 clock = GML_44KHZ;
262 /* Professional mode */
263 if (control_reg & GML_SPDIF_PRO_MODE)
264 clock |= GML_SPDIF_SAMPLE_RATE0;
265 break;
266 case 32000:
267 clock = GML_32KHZ | GML_SPDIF_SAMPLE_RATE0 |
268 GML_SPDIF_SAMPLE_RATE1;
269 break;
270 case 22050:
271 clock = GML_22KHZ;
272 break;
273 case 16000:
274 clock = GML_16KHZ;
275 break;
276 case 11025:
277 clock = GML_11KHZ;
278 break;
279 case 8000:
280 clock = GML_8KHZ;
281 break;
282 default:
283 DE_ACT(("set_sample_rate: %d invalid!\n", rate));
284 return -EINVAL;
285 }
286
287 control_reg |= clock;
288
289 chip->comm_page->sample_rate = cpu_to_le32(rate); /* ignored by the DSP */
290 chip->sample_rate = rate;
291 DE_ACT(("set_sample_rate: %d clock %d\n", rate, clock));
292
293 return write_control_reg(chip, control_reg, force_write);
294}
295
296
297
298static int set_input_clock(struct echoaudio *chip, u16 clock)
299{
300 u32 control_reg, clocks_from_dsp;
301 int err;
302
303 DE_ACT(("set_input_clock:\n"));
304
305 /* Prevent two simultaneous calls to switch_asic() */
306 if (atomic_read(&chip->opencount))
307 return -EAGAIN;
308
309 /* Mask off the clock select bits */
310 control_reg = le32_to_cpu(chip->comm_page->control_register) &
311 GML_CLOCK_CLEAR_MASK;
312 clocks_from_dsp = le32_to_cpu(chip->comm_page->status_clocks);
313
314 switch (clock) {
315 case ECHO_CLOCK_INTERNAL:
316 DE_ACT(("Set Mona clock to INTERNAL\n"));
317 chip->input_clock = ECHO_CLOCK_INTERNAL;
318 return set_sample_rate(chip, chip->sample_rate);
319 case ECHO_CLOCK_SPDIF:
320 if (chip->digital_mode == DIGITAL_MODE_ADAT)
321 return -EAGAIN;
322 spin_unlock_irq(&chip->lock);
323 err = switch_asic(chip, clocks_from_dsp &
324 GML_CLOCK_DETECT_BIT_SPDIF96);
325 spin_lock_irq(&chip->lock);
326 if (err < 0)
327 return err;
328 DE_ACT(("Set Mona clock to SPDIF\n"));
329 control_reg |= GML_SPDIF_CLOCK;
330 if (clocks_from_dsp & GML_CLOCK_DETECT_BIT_SPDIF96)
331 control_reg |= GML_DOUBLE_SPEED_MODE;
332 else
333 control_reg &= ~GML_DOUBLE_SPEED_MODE;
334 break;
335 case ECHO_CLOCK_WORD:
336 DE_ACT(("Set Mona clock to WORD\n"));
337 spin_unlock_irq(&chip->lock);
338 err = switch_asic(chip, clocks_from_dsp &
339 GML_CLOCK_DETECT_BIT_WORD96);
340 spin_lock_irq(&chip->lock);
341 if (err < 0)
342 return err;
343 control_reg |= GML_WORD_CLOCK;
344 if (clocks_from_dsp & GML_CLOCK_DETECT_BIT_WORD96)
345 control_reg |= GML_DOUBLE_SPEED_MODE;
346 else
347 control_reg &= ~GML_DOUBLE_SPEED_MODE;
348 break;
349 case ECHO_CLOCK_ADAT:
350 DE_ACT(("Set Mona clock to ADAT\n"));
351 if (chip->digital_mode != DIGITAL_MODE_ADAT)
352 return -EAGAIN;
353 control_reg |= GML_ADAT_CLOCK;
354 control_reg &= ~GML_DOUBLE_SPEED_MODE;
355 break;
356 default:
357 DE_ACT(("Input clock 0x%x not supported for Mona\n", clock));
358 return -EINVAL;
359 }
360
361 chip->input_clock = clock;
362 return write_control_reg(chip, control_reg, TRUE);
363}
364
365
366
367static int dsp_set_digital_mode(struct echoaudio *chip, u8 mode)
368{
369 u32 control_reg;
370 int err, incompatible_clock;
371
372 /* Set clock to "internal" if it's not compatible with the new mode */
373 incompatible_clock = FALSE;
374 switch (mode) {
375 case DIGITAL_MODE_SPDIF_OPTICAL:
376 case DIGITAL_MODE_SPDIF_RCA:
377 if (chip->input_clock == ECHO_CLOCK_ADAT)
378 incompatible_clock = TRUE;
379 break;
380 case DIGITAL_MODE_ADAT:
381 if (chip->input_clock == ECHO_CLOCK_SPDIF)
382 incompatible_clock = TRUE;
383 break;
384 default:
385 DE_ACT(("Digital mode not supported: %d\n", mode));
386 return -EINVAL;
387 }
388
389 spin_lock_irq(&chip->lock);
390
391 if (incompatible_clock) { /* Switch to 48KHz, internal */
392 chip->sample_rate = 48000;
393 set_input_clock(chip, ECHO_CLOCK_INTERNAL);
394 }
395
396 /* Clear the current digital mode */
397 control_reg = le32_to_cpu(chip->comm_page->control_register);
398 control_reg &= GML_DIGITAL_MODE_CLEAR_MASK;
399
400 /* Tweak the control reg */
401 switch (mode) {
402 case DIGITAL_MODE_SPDIF_OPTICAL:
403 control_reg |= GML_SPDIF_OPTICAL_MODE;
404 break;
405 case DIGITAL_MODE_SPDIF_RCA:
406 /* GML_SPDIF_OPTICAL_MODE bit cleared */
407 break;
408 case DIGITAL_MODE_ADAT:
409 /* If the current ASIC is the 96KHz ASIC, switch the ASIC
410 and set to 48 KHz */
411 if (chip->asic_code == &card_fw[FW_MONA_361_1_ASIC96] ||
412 chip->asic_code == &card_fw[FW_MONA_301_1_ASIC96]) {
413 set_sample_rate(chip, 48000);
414 }
415 control_reg |= GML_ADAT_MODE;
416 control_reg &= ~GML_DOUBLE_SPEED_MODE;
417 break;
418 }
419
420 err = write_control_reg(chip, control_reg, FALSE);
421 spin_unlock_irq(&chip->lock);
422 if (err < 0)
423 return err;
424 chip->digital_mode = mode;
425
426 DE_ACT(("set_digital_mode to %d\n", mode));
427 return incompatible_clock;
428}