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