diff options
author | Giuliano Pochini <pochini@shiny.it> | 2006-06-28 07:53:41 -0400 |
---|---|---|
committer | Jaroslav Kysela <perex@suse.cz> | 2006-06-28 13:31:20 -0400 |
commit | dd7b254d8dd3a9528f423ac3bf875e6f0c8da561 (patch) | |
tree | 923ac13451c796b730f21c7260beba9f74acff63 /sound/pci/echoaudio/echoaudio_3g.c | |
parent | cb9d24e4349013628259b5fee97e692173731b07 (diff) |
[ALSA] Add echoaudio sound drivers
From: Giuliano Pochini <pochini@shiny.it>Add echoaudio sound drivers (darla20, darla24, echo3g, gina20, gina24,
indigo, indigodj, indigoio, layla20, lala24, mia, mona)
Signed-off-by: Takashi Iwai <tiwai@suse.de>
Signed-off-by: Jaroslav Kysela <perex@suse.cz>
Diffstat (limited to 'sound/pci/echoaudio/echoaudio_3g.c')
-rw-r--r-- | sound/pci/echoaudio/echoaudio_3g.c | 431 |
1 files changed, 431 insertions, 0 deletions
diff --git a/sound/pci/echoaudio/echoaudio_3g.c b/sound/pci/echoaudio/echoaudio_3g.c new file mode 100644 index 000000000000..9f439ea459f4 --- /dev/null +++ b/sound/pci/echoaudio/echoaudio_3g.c | |||
@@ -0,0 +1,431 @@ | |||
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 | |||
33 | /* These functions are common for all "3G" cards */ | ||
34 | |||
35 | |||
36 | static int check_asic_status(struct echoaudio *chip) | ||
37 | { | ||
38 | u32 box_status; | ||
39 | |||
40 | if (wait_handshake(chip)) | ||
41 | return -EIO; | ||
42 | |||
43 | chip->comm_page->ext_box_status = | ||
44 | __constant_cpu_to_le32(E3G_ASIC_NOT_LOADED); | ||
45 | chip->asic_loaded = FALSE; | ||
46 | clear_handshake(chip); | ||
47 | send_vector(chip, DSP_VC_TEST_ASIC); | ||
48 | |||
49 | if (wait_handshake(chip)) { | ||
50 | chip->dsp_code = NULL; | ||
51 | return -EIO; | ||
52 | } | ||
53 | |||
54 | box_status = le32_to_cpu(chip->comm_page->ext_box_status); | ||
55 | DE_INIT(("box_status=%x\n", box_status)); | ||
56 | if (box_status == E3G_ASIC_NOT_LOADED) | ||
57 | return -ENODEV; | ||
58 | |||
59 | chip->asic_loaded = TRUE; | ||
60 | return box_status & E3G_BOX_TYPE_MASK; | ||
61 | } | ||
62 | |||
63 | |||
64 | |||
65 | static inline u32 get_frq_reg(struct echoaudio *chip) | ||
66 | { | ||
67 | return le32_to_cpu(chip->comm_page->e3g_frq_register); | ||
68 | } | ||
69 | |||
70 | |||
71 | |||
72 | /* Most configuration of 3G cards is accomplished by writing the control | ||
73 | register. write_control_reg sends the new control register value to the DSP. */ | ||
74 | static int write_control_reg(struct echoaudio *chip, u32 ctl, u32 frq, | ||
75 | char force) | ||
76 | { | ||
77 | if (wait_handshake(chip)) | ||
78 | return -EIO; | ||
79 | |||
80 | DE_ACT(("WriteControlReg: Setting 0x%x, 0x%x\n", ctl, frq)); | ||
81 | |||
82 | ctl = cpu_to_le32(ctl); | ||
83 | frq = cpu_to_le32(frq); | ||
84 | |||
85 | if (ctl != chip->comm_page->control_register || | ||
86 | frq != chip->comm_page->e3g_frq_register || force) { | ||
87 | chip->comm_page->e3g_frq_register = frq; | ||
88 | chip->comm_page->control_register = ctl; | ||
89 | clear_handshake(chip); | ||
90 | return send_vector(chip, DSP_VC_WRITE_CONTROL_REG); | ||
91 | } | ||
92 | |||
93 | DE_ACT(("WriteControlReg: not written, no change\n")); | ||
94 | return 0; | ||
95 | } | ||
96 | |||
97 | |||
98 | |||
99 | /* Set the digital mode - currently for Gina24, Layla24, Mona, 3G */ | ||
100 | static int set_digital_mode(struct echoaudio *chip, u8 mode) | ||
101 | { | ||
102 | u8 previous_mode; | ||
103 | int err, i, o; | ||
104 | |||
105 | /* All audio channels must be closed before changing the digital mode */ | ||
106 | snd_assert(!chip->pipe_alloc_mask, return -EAGAIN); | ||
107 | |||
108 | snd_assert(chip->digital_modes & (1 << mode), return -EINVAL); | ||
109 | |||
110 | previous_mode = chip->digital_mode; | ||
111 | err = dsp_set_digital_mode(chip, mode); | ||
112 | |||
113 | /* If we successfully changed the digital mode from or to ADAT, | ||
114 | * then make sure all output, input and monitor levels are | ||
115 | * updated by the DSP comm object. */ | ||
116 | if (err >= 0 && previous_mode != mode && | ||
117 | (previous_mode == DIGITAL_MODE_ADAT || mode == DIGITAL_MODE_ADAT)) { | ||
118 | spin_lock_irq(&chip->lock); | ||
119 | for (o = 0; o < num_busses_out(chip); o++) | ||
120 | for (i = 0; i < num_busses_in(chip); i++) | ||
121 | set_monitor_gain(chip, o, i, | ||
122 | chip->monitor_gain[o][i]); | ||
123 | |||
124 | #ifdef ECHOCARD_HAS_INPUT_GAIN | ||
125 | for (i = 0; i < num_busses_in(chip); i++) | ||
126 | set_input_gain(chip, i, chip->input_gain[i]); | ||
127 | update_input_line_level(chip); | ||
128 | #endif | ||
129 | |||
130 | for (o = 0; o < num_busses_out(chip); o++) | ||
131 | set_output_gain(chip, o, chip->output_gain[o]); | ||
132 | update_output_line_level(chip); | ||
133 | spin_unlock_irq(&chip->lock); | ||
134 | } | ||
135 | |||
136 | return err; | ||
137 | } | ||
138 | |||
139 | |||
140 | |||
141 | static u32 set_spdif_bits(struct echoaudio *chip, u32 control_reg, u32 rate) | ||
142 | { | ||
143 | control_reg &= E3G_SPDIF_FORMAT_CLEAR_MASK; | ||
144 | |||
145 | switch (rate) { | ||
146 | case 32000 : | ||
147 | control_reg |= E3G_SPDIF_SAMPLE_RATE0 | E3G_SPDIF_SAMPLE_RATE1; | ||
148 | break; | ||
149 | case 44100 : | ||
150 | if (chip->professional_spdif) | ||
151 | control_reg |= E3G_SPDIF_SAMPLE_RATE0; | ||
152 | break; | ||
153 | case 48000 : | ||
154 | control_reg |= E3G_SPDIF_SAMPLE_RATE1; | ||
155 | break; | ||
156 | } | ||
157 | |||
158 | if (chip->professional_spdif) | ||
159 | control_reg |= E3G_SPDIF_PRO_MODE; | ||
160 | |||
161 | if (chip->non_audio_spdif) | ||
162 | control_reg |= E3G_SPDIF_NOT_AUDIO; | ||
163 | |||
164 | control_reg |= E3G_SPDIF_24_BIT | E3G_SPDIF_TWO_CHANNEL | | ||
165 | E3G_SPDIF_COPY_PERMIT; | ||
166 | |||
167 | return control_reg; | ||
168 | } | ||
169 | |||
170 | |||
171 | |||
172 | /* Set the S/PDIF output format */ | ||
173 | static int set_professional_spdif(struct echoaudio *chip, char prof) | ||
174 | { | ||
175 | u32 control_reg; | ||
176 | |||
177 | control_reg = le32_to_cpu(chip->comm_page->control_register); | ||
178 | chip->professional_spdif = prof; | ||
179 | control_reg = set_spdif_bits(chip, control_reg, chip->sample_rate); | ||
180 | return write_control_reg(chip, control_reg, get_frq_reg(chip), 0); | ||
181 | } | ||
182 | |||
183 | |||
184 | |||
185 | /* detect_input_clocks() returns a bitmask consisting of all the input clocks | ||
186 | currently connected to the hardware; this changes as the user connects and | ||
187 | disconnects clock inputs. You should use this information to determine which | ||
188 | clocks the user is allowed to select. */ | ||
189 | static u32 detect_input_clocks(const struct echoaudio *chip) | ||
190 | { | ||
191 | u32 clocks_from_dsp, clock_bits; | ||
192 | |||
193 | /* Map the DSP clock detect bits to the generic driver clock | ||
194 | * detect bits */ | ||
195 | clocks_from_dsp = le32_to_cpu(chip->comm_page->status_clocks); | ||
196 | |||
197 | clock_bits = ECHO_CLOCK_BIT_INTERNAL; | ||
198 | |||
199 | if (clocks_from_dsp & E3G_CLOCK_DETECT_BIT_WORD) | ||
200 | clock_bits |= ECHO_CLOCK_BIT_WORD; | ||
201 | |||
202 | switch(chip->digital_mode) { | ||
203 | case DIGITAL_MODE_SPDIF_RCA: | ||
204 | case DIGITAL_MODE_SPDIF_OPTICAL: | ||
205 | if (clocks_from_dsp & E3G_CLOCK_DETECT_BIT_SPDIF) | ||
206 | clock_bits |= ECHO_CLOCK_BIT_SPDIF; | ||
207 | break; | ||
208 | case DIGITAL_MODE_ADAT: | ||
209 | if (clocks_from_dsp & E3G_CLOCK_DETECT_BIT_ADAT) | ||
210 | clock_bits |= ECHO_CLOCK_BIT_ADAT; | ||
211 | break; | ||
212 | } | ||
213 | |||
214 | return clock_bits; | ||
215 | } | ||
216 | |||
217 | |||
218 | |||
219 | static int load_asic(struct echoaudio *chip) | ||
220 | { | ||
221 | int box_type, err; | ||
222 | |||
223 | if (chip->asic_loaded) | ||
224 | return 0; | ||
225 | |||
226 | /* Give the DSP a few milliseconds to settle down */ | ||
227 | mdelay(2); | ||
228 | |||
229 | err = load_asic_generic(chip, DSP_FNC_LOAD_3G_ASIC, | ||
230 | &card_fw[FW_3G_ASIC]); | ||
231 | if (err < 0) | ||
232 | return err; | ||
233 | |||
234 | chip->asic_code = &card_fw[FW_3G_ASIC]; | ||
235 | |||
236 | /* Now give the new ASIC a little time to set up */ | ||
237 | mdelay(2); | ||
238 | /* See if it worked */ | ||
239 | box_type = check_asic_status(chip); | ||
240 | |||
241 | /* Set up the control register if the load succeeded - | ||
242 | * 48 kHz, internal clock, S/PDIF RCA mode */ | ||
243 | if (box_type >= 0) { | ||
244 | err = write_control_reg(chip, E3G_48KHZ, | ||
245 | E3G_FREQ_REG_DEFAULT, TRUE); | ||
246 | if (err < 0) | ||
247 | return err; | ||
248 | } | ||
249 | |||
250 | return box_type; | ||
251 | } | ||
252 | |||
253 | |||
254 | |||
255 | static int set_sample_rate(struct echoaudio *chip, u32 rate) | ||
256 | { | ||
257 | u32 control_reg, clock, base_rate, frq_reg; | ||
258 | |||
259 | /* Only set the clock for internal mode. */ | ||
260 | if (chip->input_clock != ECHO_CLOCK_INTERNAL) { | ||
261 | DE_ACT(("set_sample_rate: Cannot set sample rate - " | ||
262 | "clock not set to CLK_CLOCKININTERNAL\n")); | ||
263 | /* Save the rate anyhow */ | ||
264 | chip->comm_page->sample_rate = cpu_to_le32(rate); | ||
265 | chip->sample_rate = rate; | ||
266 | set_input_clock(chip, chip->input_clock); | ||
267 | return 0; | ||
268 | } | ||
269 | |||
270 | snd_assert(rate < 50000 || chip->digital_mode != DIGITAL_MODE_ADAT, | ||
271 | return -EINVAL); | ||
272 | |||
273 | clock = 0; | ||
274 | control_reg = le32_to_cpu(chip->comm_page->control_register); | ||
275 | control_reg &= E3G_CLOCK_CLEAR_MASK; | ||
276 | |||
277 | switch (rate) { | ||
278 | case 96000: | ||
279 | clock = E3G_96KHZ; | ||
280 | break; | ||
281 | case 88200: | ||
282 | clock = E3G_88KHZ; | ||
283 | break; | ||
284 | case 48000: | ||
285 | clock = E3G_48KHZ; | ||
286 | break; | ||
287 | case 44100: | ||
288 | clock = E3G_44KHZ; | ||
289 | break; | ||
290 | case 32000: | ||
291 | clock = E3G_32KHZ; | ||
292 | break; | ||
293 | default: | ||
294 | clock = E3G_CONTINUOUS_CLOCK; | ||
295 | if (rate > 50000) | ||
296 | clock |= E3G_DOUBLE_SPEED_MODE; | ||
297 | break; | ||
298 | } | ||
299 | |||
300 | control_reg |= clock; | ||
301 | control_reg = set_spdif_bits(chip, control_reg, rate); | ||
302 | |||
303 | base_rate = rate; | ||
304 | if (base_rate > 50000) | ||
305 | base_rate /= 2; | ||
306 | if (base_rate < 32000) | ||
307 | base_rate = 32000; | ||
308 | |||
309 | frq_reg = E3G_MAGIC_NUMBER / base_rate - 2; | ||
310 | if (frq_reg > E3G_FREQ_REG_MAX) | ||
311 | frq_reg = E3G_FREQ_REG_MAX; | ||
312 | |||
313 | chip->comm_page->sample_rate = cpu_to_le32(rate); /* ignored by the DSP */ | ||
314 | chip->sample_rate = rate; | ||
315 | DE_ACT(("SetSampleRate: %d clock %x\n", rate, control_reg)); | ||
316 | |||
317 | /* Tell the DSP about it - DSP reads both control reg & freq reg */ | ||
318 | return write_control_reg(chip, control_reg, frq_reg, 0); | ||
319 | } | ||
320 | |||
321 | |||
322 | |||
323 | /* Set the sample clock source to internal, S/PDIF, ADAT */ | ||
324 | static int set_input_clock(struct echoaudio *chip, u16 clock) | ||
325 | { | ||
326 | u32 control_reg, clocks_from_dsp; | ||
327 | |||
328 | DE_ACT(("set_input_clock:\n")); | ||
329 | |||
330 | /* Mask off the clock select bits */ | ||
331 | control_reg = le32_to_cpu(chip->comm_page->control_register) & | ||
332 | E3G_CLOCK_CLEAR_MASK; | ||
333 | clocks_from_dsp = le32_to_cpu(chip->comm_page->status_clocks); | ||
334 | |||
335 | switch (clock) { | ||
336 | case ECHO_CLOCK_INTERNAL: | ||
337 | DE_ACT(("Set Echo3G clock to INTERNAL\n")); | ||
338 | chip->input_clock = ECHO_CLOCK_INTERNAL; | ||
339 | return set_sample_rate(chip, chip->sample_rate); | ||
340 | case ECHO_CLOCK_SPDIF: | ||
341 | if (chip->digital_mode == DIGITAL_MODE_ADAT) | ||
342 | return -EAGAIN; | ||
343 | DE_ACT(("Set Echo3G clock to SPDIF\n")); | ||
344 | control_reg |= E3G_SPDIF_CLOCK; | ||
345 | if (clocks_from_dsp & E3G_CLOCK_DETECT_BIT_SPDIF96) | ||
346 | control_reg |= E3G_DOUBLE_SPEED_MODE; | ||
347 | else | ||
348 | control_reg &= ~E3G_DOUBLE_SPEED_MODE; | ||
349 | break; | ||
350 | case ECHO_CLOCK_ADAT: | ||
351 | if (chip->digital_mode != DIGITAL_MODE_ADAT) | ||
352 | return -EAGAIN; | ||
353 | DE_ACT(("Set Echo3G clock to ADAT\n")); | ||
354 | control_reg |= E3G_ADAT_CLOCK; | ||
355 | control_reg &= ~E3G_DOUBLE_SPEED_MODE; | ||
356 | break; | ||
357 | case ECHO_CLOCK_WORD: | ||
358 | DE_ACT(("Set Echo3G clock to WORD\n")); | ||
359 | control_reg |= E3G_WORD_CLOCK; | ||
360 | if (clocks_from_dsp & E3G_CLOCK_DETECT_BIT_WORD96) | ||
361 | control_reg |= E3G_DOUBLE_SPEED_MODE; | ||
362 | else | ||
363 | control_reg &= ~E3G_DOUBLE_SPEED_MODE; | ||
364 | break; | ||
365 | default: | ||
366 | DE_ACT(("Input clock 0x%x not supported for Echo3G\n", clock)); | ||
367 | return -EINVAL; | ||
368 | } | ||
369 | |||
370 | chip->input_clock = clock; | ||
371 | return write_control_reg(chip, control_reg, get_frq_reg(chip), 1); | ||
372 | } | ||
373 | |||
374 | |||
375 | |||
376 | static int dsp_set_digital_mode(struct echoaudio *chip, u8 mode) | ||
377 | { | ||
378 | u32 control_reg; | ||
379 | int err, incompatible_clock; | ||
380 | |||
381 | /* Set clock to "internal" if it's not compatible with the new mode */ | ||
382 | incompatible_clock = FALSE; | ||
383 | switch (mode) { | ||
384 | case DIGITAL_MODE_SPDIF_OPTICAL: | ||
385 | case DIGITAL_MODE_SPDIF_RCA: | ||
386 | if (chip->input_clock == ECHO_CLOCK_ADAT) | ||
387 | incompatible_clock = TRUE; | ||
388 | break; | ||
389 | case DIGITAL_MODE_ADAT: | ||
390 | if (chip->input_clock == ECHO_CLOCK_SPDIF) | ||
391 | incompatible_clock = TRUE; | ||
392 | break; | ||
393 | default: | ||
394 | DE_ACT(("Digital mode not supported: %d\n", mode)); | ||
395 | return -EINVAL; | ||
396 | } | ||
397 | |||
398 | spin_lock_irq(&chip->lock); | ||
399 | |||
400 | if (incompatible_clock) { | ||
401 | chip->sample_rate = 48000; | ||
402 | set_input_clock(chip, ECHO_CLOCK_INTERNAL); | ||
403 | } | ||
404 | |||
405 | /* Clear the current digital mode */ | ||
406 | control_reg = le32_to_cpu(chip->comm_page->control_register); | ||
407 | control_reg &= E3G_DIGITAL_MODE_CLEAR_MASK; | ||
408 | |||
409 | /* Tweak the control reg */ | ||
410 | switch (mode) { | ||
411 | case DIGITAL_MODE_SPDIF_OPTICAL: | ||
412 | control_reg |= E3G_SPDIF_OPTICAL_MODE; | ||
413 | break; | ||
414 | case DIGITAL_MODE_SPDIF_RCA: | ||
415 | /* E3G_SPDIF_OPTICAL_MODE bit cleared */ | ||
416 | break; | ||
417 | case DIGITAL_MODE_ADAT: | ||
418 | control_reg |= E3G_ADAT_MODE; | ||
419 | control_reg &= ~E3G_DOUBLE_SPEED_MODE; /* @@ useless */ | ||
420 | break; | ||
421 | } | ||
422 | |||
423 | err = write_control_reg(chip, control_reg, get_frq_reg(chip), 1); | ||
424 | spin_unlock_irq(&chip->lock); | ||
425 | if (err < 0) | ||
426 | return err; | ||
427 | chip->digital_mode = mode; | ||
428 | |||
429 | DE_ACT(("set_digital_mode(%d)\n", chip->digital_mode)); | ||
430 | return incompatible_clock; | ||
431 | } | ||