aboutsummaryrefslogtreecommitdiffstats
path: root/sound/pci/echoaudio/layla24_dsp.c
diff options
context:
space:
mode:
Diffstat (limited to 'sound/pci/echoaudio/layla24_dsp.c')
-rw-r--r--sound/pci/echoaudio/layla24_dsp.c394
1 files changed, 394 insertions, 0 deletions
diff --git a/sound/pci/echoaudio/layla24_dsp.c b/sound/pci/echoaudio/layla24_dsp.c
new file mode 100644
index 000000000000..7ec5b63d0dce
--- /dev/null
+++ b/sound/pci/echoaudio/layla24_dsp.c
@@ -0,0 +1,394 @@
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 Foundation.
12
13 This program is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
17
18 You should have received a copy of the GNU General Public License
19 along with this program; if not, write to the Free Software
20 Foundation, Inc., 59 Temple Place - Suite 330, Boston,
21 MA 02111-1307, USA.
22
23 *************************************************************************
24
25 Translation from C++ and adaptation for use in ALSA-Driver
26 were made by Giuliano Pochini <pochini@shiny.it>
27
28****************************************************************************/
29
30
31static int write_control_reg(struct echoaudio *chip, u32 value, char force);
32static int set_input_clock(struct echoaudio *chip, u16 clock);
33static int set_professional_spdif(struct echoaudio *chip, char prof);
34static int set_digital_mode(struct echoaudio *chip, u8 mode);
35static int load_asic_generic(struct echoaudio *chip, u32 cmd,
36 const struct firmware *asic);
37static int check_asic_status(struct echoaudio *chip);
38
39
40static int init_hw(struct echoaudio *chip, u16 device_id, u16 subdevice_id)
41{
42 int err;
43
44 DE_INIT(("init_hw() - Layla24\n"));
45 snd_assert((subdevice_id & 0xfff0) == LAYLA24, 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_LAYLA24_DSP];
57 chip->input_clock_types =
58 ECHO_CLOCK_BIT_INTERNAL | ECHO_CLOCK_BIT_SPDIF |
59 ECHO_CLOCK_BIT_WORD | ECHO_CLOCK_BIT_ADAT;
60 chip->digital_modes =
61 ECHOCAPS_HAS_DIGITAL_MODE_SPDIF_RCA |
62 ECHOCAPS_HAS_DIGITAL_MODE_SPDIF_OPTICAL |
63 ECHOCAPS_HAS_DIGITAL_MODE_ADAT;
64 chip->digital_mode = DIGITAL_MODE_SPDIF_RCA;
65 chip->professional_spdif = FALSE;
66 chip->digital_in_automute = TRUE;
67
68 if ((err = load_firmware(chip)) < 0)
69 return err;
70 chip->bad_board = FALSE;
71
72 if ((err = init_line_levels(chip)) < 0)
73 return err;
74
75 err = set_digital_mode(chip, DIGITAL_MODE_SPDIF_RCA);
76 snd_assert(err >= 0, return err);
77 err = set_professional_spdif(chip, TRUE);
78
79 DE_INIT(("init_hw done\n"));
80 return err;
81}
82
83
84
85static u32 detect_input_clocks(const struct echoaudio *chip)
86{
87 u32 clocks_from_dsp, clock_bits;
88
89 /* Map the DSP clock detect bits to the generic driver clock detect bits */
90 clocks_from_dsp = le32_to_cpu(chip->comm_page->status_clocks);
91
92 clock_bits = ECHO_CLOCK_BIT_INTERNAL;
93
94 if (clocks_from_dsp & GML_CLOCK_DETECT_BIT_SPDIF)
95 clock_bits |= ECHO_CLOCK_BIT_SPDIF;
96
97 if (clocks_from_dsp & GML_CLOCK_DETECT_BIT_ADAT)
98 clock_bits |= ECHO_CLOCK_BIT_ADAT;
99
100 if (clocks_from_dsp & GML_CLOCK_DETECT_BIT_WORD)
101 clock_bits |= ECHO_CLOCK_BIT_WORD;
102
103 return clock_bits;
104}
105
106
107
108/* Layla24 has an ASIC on the PCI card and another ASIC in the external box;
109both need to be loaded. */
110static int load_asic(struct echoaudio *chip)
111{
112 int err;
113
114 if (chip->asic_loaded)
115 return 1;
116
117 DE_INIT(("load_asic\n"));
118
119 /* Give the DSP a few milliseconds to settle down */
120 mdelay(10);
121
122 /* Load the ASIC for the PCI card */
123 err = load_asic_generic(chip, DSP_FNC_LOAD_LAYLA24_PCI_CARD_ASIC,
124 &card_fw[FW_LAYLA24_1_ASIC]);
125 if (err < 0)
126 return err;
127
128 chip->asic_code = &card_fw[FW_LAYLA24_2S_ASIC];
129
130 /* Now give the new ASIC a little time to set up */
131 mdelay(10);
132
133 /* Do the external one */
134 err = load_asic_generic(chip, DSP_FNC_LOAD_LAYLA24_EXTERNAL_ASIC,
135 &card_fw[FW_LAYLA24_2S_ASIC]);
136 if (err < 0)
137 return FALSE;
138
139 /* Now give the external ASIC a little time to set up */
140 mdelay(10);
141
142 /* See if it worked */
143 err = check_asic_status(chip);
144
145 /* Set up the control register if the load succeeded -
146 48 kHz, internal clock, S/PDIF RCA mode */
147 if (!err)
148 err = write_control_reg(chip, GML_CONVERTER_ENABLE | GML_48KHZ,
149 TRUE);
150
151 DE_INIT(("load_asic() done\n"));
152 return err;
153}
154
155
156
157static int set_sample_rate(struct echoaudio *chip, u32 rate)
158{
159 u32 control_reg, clock, base_rate;
160
161 snd_assert(rate < 50000 || chip->digital_mode != DIGITAL_MODE_ADAT,
162 return -EINVAL);
163
164 /* Only set the clock for internal mode. */
165 if (chip->input_clock != ECHO_CLOCK_INTERNAL) {
166 DE_ACT(("set_sample_rate: Cannot set sample rate - "
167 "clock not set to CLK_CLOCKININTERNAL\n"));
168 /* Save the rate anyhow */
169 chip->comm_page->sample_rate = cpu_to_le32(rate);
170 chip->sample_rate = rate;
171 return 0;
172 }
173
174 /* Get the control register & clear the appropriate bits */
175 control_reg = le32_to_cpu(chip->comm_page->control_register);
176 control_reg &= GML_CLOCK_CLEAR_MASK & GML_SPDIF_RATE_CLEAR_MASK;
177
178 clock = 0;
179
180 switch (rate) {
181 case 96000:
182 clock = GML_96KHZ;
183 break;
184 case 88200:
185 clock = GML_88KHZ;
186 break;
187 case 48000:
188 clock = GML_48KHZ | GML_SPDIF_SAMPLE_RATE1;
189 break;
190 case 44100:
191 clock = GML_44KHZ;
192 /* Professional mode */
193 if (control_reg & GML_SPDIF_PRO_MODE)
194 clock |= GML_SPDIF_SAMPLE_RATE0;
195 break;
196 case 32000:
197 clock = GML_32KHZ | GML_SPDIF_SAMPLE_RATE0 |
198 GML_SPDIF_SAMPLE_RATE1;
199 break;
200 case 22050:
201 clock = GML_22KHZ;
202 break;
203 case 16000:
204 clock = GML_16KHZ;
205 break;
206 case 11025:
207 clock = GML_11KHZ;
208 break;
209 case 8000:
210 clock = GML_8KHZ;
211 break;
212 default:
213 /* If this is a non-standard rate, then the driver needs to
214 use Layla24's special "continuous frequency" mode */
215 clock = LAYLA24_CONTINUOUS_CLOCK;
216 if (rate > 50000) {
217 base_rate = rate >> 1;
218 control_reg |= GML_DOUBLE_SPEED_MODE;
219 } else {
220 base_rate = rate;
221 }
222
223 if (base_rate < 25000)
224 base_rate = 25000;
225
226 if (wait_handshake(chip))
227 return -EIO;
228
229 chip->comm_page->sample_rate =
230 cpu_to_le32(LAYLA24_MAGIC_NUMBER / base_rate - 2);
231
232 clear_handshake(chip);
233 send_vector(chip, DSP_VC_SET_LAYLA24_FREQUENCY_REG);
234 }
235
236 control_reg |= clock;
237
238 chip->comm_page->sample_rate = cpu_to_le32(rate); /* ignored by the DSP ? */
239 chip->sample_rate = rate;
240 DE_ACT(("set_sample_rate: %d clock %d\n", rate, control_reg));
241
242 return write_control_reg(chip, control_reg, FALSE);
243}
244
245
246
247static int set_input_clock(struct echoaudio *chip, u16 clock)
248{
249 u32 control_reg, clocks_from_dsp;
250
251 /* Mask off the clock select bits */
252 control_reg = le32_to_cpu(chip->comm_page->control_register) &
253 GML_CLOCK_CLEAR_MASK;
254 clocks_from_dsp = le32_to_cpu(chip->comm_page->status_clocks);
255
256 /* Pick the new clock */
257 switch (clock) {
258 case ECHO_CLOCK_INTERNAL:
259 DE_ACT(("Set Layla24 clock to INTERNAL\n"));
260 chip->input_clock = ECHO_CLOCK_INTERNAL;
261 return set_sample_rate(chip, chip->sample_rate);
262 case ECHO_CLOCK_SPDIF:
263 if (chip->digital_mode == DIGITAL_MODE_ADAT)
264 return -EAGAIN;
265 control_reg |= GML_SPDIF_CLOCK;
266 /* Layla24 doesn't support 96KHz S/PDIF */
267 control_reg &= ~GML_DOUBLE_SPEED_MODE;
268 DE_ACT(("Set Layla24 clock to SPDIF\n"));
269 break;
270 case ECHO_CLOCK_WORD:
271 control_reg |= GML_WORD_CLOCK;
272 if (clocks_from_dsp & GML_CLOCK_DETECT_BIT_WORD96)
273 control_reg |= GML_DOUBLE_SPEED_MODE;
274 else
275 control_reg &= ~GML_DOUBLE_SPEED_MODE;
276 DE_ACT(("Set Layla24 clock to WORD\n"));
277 break;
278 case ECHO_CLOCK_ADAT:
279 if (chip->digital_mode != DIGITAL_MODE_ADAT)
280 return -EAGAIN;
281 control_reg |= GML_ADAT_CLOCK;
282 control_reg &= ~GML_DOUBLE_SPEED_MODE;
283 DE_ACT(("Set Layla24 clock to ADAT\n"));
284 break;
285 default:
286 DE_ACT(("Input clock 0x%x not supported for Layla24\n", clock));
287 return -EINVAL;
288 }
289
290 chip->input_clock = clock;
291 return write_control_reg(chip, control_reg, TRUE);
292}
293
294
295
296/* Depending on what digital mode you want, Layla24 needs different ASICs
297loaded. This function checks the ASIC needed for the new mode and sees
298if it matches the one already loaded. */
299static int switch_asic(struct echoaudio *chip, const struct firmware *asic)
300{
301 s8 *monitors;
302
303 /* Check to see if this is already loaded */
304 if (asic != chip->asic_code) {
305 monitors = kmalloc(MONITOR_ARRAY_SIZE, GFP_KERNEL);
306 if (! monitors)
307 return -ENOMEM;
308
309 memcpy(monitors, chip->comm_page->monitors, MONITOR_ARRAY_SIZE);
310 memset(chip->comm_page->monitors, ECHOGAIN_MUTED,
311 MONITOR_ARRAY_SIZE);
312
313 /* Load the desired ASIC */
314 if (load_asic_generic(chip, DSP_FNC_LOAD_LAYLA24_EXTERNAL_ASIC,
315 asic) < 0) {
316 memcpy(chip->comm_page->monitors, monitors,
317 MONITOR_ARRAY_SIZE);
318 kfree(monitors);
319 return -EIO;
320 }
321 chip->asic_code = asic;
322 memcpy(chip->comm_page->monitors, monitors, MONITOR_ARRAY_SIZE);
323 kfree(monitors);
324 }
325
326 return 0;
327}
328
329
330
331static int dsp_set_digital_mode(struct echoaudio *chip, u8 mode)
332{
333 u32 control_reg;
334 int err, incompatible_clock;
335 const struct firmware *asic;
336
337 /* Set clock to "internal" if it's not compatible with the new mode */
338 incompatible_clock = FALSE;
339 switch (mode) {
340 case DIGITAL_MODE_SPDIF_OPTICAL:
341 case DIGITAL_MODE_SPDIF_RCA:
342 if (chip->input_clock == ECHO_CLOCK_ADAT)
343 incompatible_clock = TRUE;
344 asic = &card_fw[FW_LAYLA24_2S_ASIC];
345 break;
346 case DIGITAL_MODE_ADAT:
347 if (chip->input_clock == ECHO_CLOCK_SPDIF)
348 incompatible_clock = TRUE;
349 asic = &card_fw[FW_LAYLA24_2A_ASIC];
350 break;
351 default:
352 DE_ACT(("Digital mode not supported: %d\n", mode));
353 return -EINVAL;
354 }
355
356 if (incompatible_clock) { /* Switch to 48KHz, internal */
357 chip->sample_rate = 48000;
358 spin_lock_irq(&chip->lock);
359 set_input_clock(chip, ECHO_CLOCK_INTERNAL);
360 spin_unlock_irq(&chip->lock);
361 }
362
363 /* switch_asic() can sleep */
364 if (switch_asic(chip, asic) < 0)
365 return -EIO;
366
367 spin_lock_irq(&chip->lock);
368
369 /* Tweak the control register */
370 control_reg = le32_to_cpu(chip->comm_page->control_register);
371 control_reg &= GML_DIGITAL_MODE_CLEAR_MASK;
372
373 switch (mode) {
374 case DIGITAL_MODE_SPDIF_OPTICAL:
375 control_reg |= GML_SPDIF_OPTICAL_MODE;
376 break;
377 case DIGITAL_MODE_SPDIF_RCA:
378 /* GML_SPDIF_OPTICAL_MODE bit cleared */
379 break;
380 case DIGITAL_MODE_ADAT:
381 control_reg |= GML_ADAT_MODE;
382 control_reg &= ~GML_DOUBLE_SPEED_MODE;
383 break;
384 }
385
386 err = write_control_reg(chip, control_reg, TRUE);
387 spin_unlock_irq(&chip->lock);
388 if (err < 0)
389 return err;
390 chip->digital_mode = mode;
391
392 DE_ACT(("set_digital_mode to %d\n", mode));
393 return incompatible_clock;
394}