Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
torvalds
GitHub Repository: torvalds/linux
Path: blob/master/sound/pci/echoaudio/layla24_dsp.c
26451 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
if (snd_BUG_ON((subdevice_id & 0xfff0) != LAYLA24))
44
return -ENODEV;
45
46
err = init_dsp_comm_page(chip);
47
if (err) {
48
dev_err(chip->card->dev,
49
"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->has_midi = true;
57
chip->dsp_code_to_load = FW_LAYLA24_DSP;
58
chip->input_clock_types =
59
ECHO_CLOCK_BIT_INTERNAL | ECHO_CLOCK_BIT_SPDIF |
60
ECHO_CLOCK_BIT_WORD | ECHO_CLOCK_BIT_ADAT;
61
chip->digital_modes =
62
ECHOCAPS_HAS_DIGITAL_MODE_SPDIF_RCA |
63
ECHOCAPS_HAS_DIGITAL_MODE_SPDIF_OPTICAL |
64
ECHOCAPS_HAS_DIGITAL_MODE_ADAT;
65
66
err = load_firmware(chip);
67
if (err < 0)
68
return err;
69
chip->bad_board = false;
70
71
err = init_line_levels(chip);
72
if (err < 0)
73
return err;
74
75
return err;
76
}
77
78
79
80
static int set_mixer_defaults(struct echoaudio *chip)
81
{
82
chip->digital_mode = DIGITAL_MODE_SPDIF_RCA;
83
chip->professional_spdif = false;
84
chip->digital_in_automute = true;
85
return init_line_levels(chip);
86
}
87
88
89
90
static u32 detect_input_clocks(const struct echoaudio *chip)
91
{
92
u32 clocks_from_dsp, clock_bits;
93
94
/* Map the DSP clock detect bits to the generic driver clock detect bits */
95
clocks_from_dsp = le32_to_cpu(chip->comm_page->status_clocks);
96
97
clock_bits = ECHO_CLOCK_BIT_INTERNAL;
98
99
if (clocks_from_dsp & GML_CLOCK_DETECT_BIT_SPDIF)
100
clock_bits |= ECHO_CLOCK_BIT_SPDIF;
101
102
if (clocks_from_dsp & GML_CLOCK_DETECT_BIT_ADAT)
103
clock_bits |= ECHO_CLOCK_BIT_ADAT;
104
105
if (clocks_from_dsp & GML_CLOCK_DETECT_BIT_WORD)
106
clock_bits |= ECHO_CLOCK_BIT_WORD;
107
108
return clock_bits;
109
}
110
111
112
113
/* Layla24 has an ASIC on the PCI card and another ASIC in the external box;
114
both need to be loaded. */
115
static int load_asic(struct echoaudio *chip)
116
{
117
int err;
118
119
if (chip->asic_loaded)
120
return 1;
121
122
123
/* Give the DSP a few milliseconds to settle down */
124
mdelay(10);
125
126
/* Load the ASIC for the PCI card */
127
err = load_asic_generic(chip, DSP_FNC_LOAD_LAYLA24_PCI_CARD_ASIC,
128
FW_LAYLA24_1_ASIC);
129
if (err < 0)
130
return err;
131
132
chip->asic_code = FW_LAYLA24_2S_ASIC;
133
134
/* Now give the new ASIC a little time to set up */
135
mdelay(10);
136
137
/* Do the external one */
138
err = load_asic_generic(chip, DSP_FNC_LOAD_LAYLA24_EXTERNAL_ASIC,
139
FW_LAYLA24_2S_ASIC);
140
if (err < 0)
141
return err;
142
143
/* Now give the external ASIC a little time to set up */
144
mdelay(10);
145
146
/* See if it worked */
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
err = write_control_reg(chip, GML_CONVERTER_ENABLE | GML_48KHZ,
153
true);
154
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
dev_warn(chip->card->dev,
171
"Cannot set sample rate - 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
dev_dbg(chip->card->dev,
245
"set_sample_rate: %d clock %d\n", rate, control_reg);
246
247
return write_control_reg(chip, control_reg, false);
248
}
249
250
251
252
static int set_input_clock(struct echoaudio *chip, u16 clock)
253
{
254
u32 control_reg, clocks_from_dsp;
255
256
/* Mask off the clock select bits */
257
control_reg = le32_to_cpu(chip->comm_page->control_register) &
258
GML_CLOCK_CLEAR_MASK;
259
clocks_from_dsp = le32_to_cpu(chip->comm_page->status_clocks);
260
261
/* Pick the new clock */
262
switch (clock) {
263
case ECHO_CLOCK_INTERNAL:
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
break;
273
case ECHO_CLOCK_WORD:
274
control_reg |= GML_WORD_CLOCK;
275
if (clocks_from_dsp & GML_CLOCK_DETECT_BIT_WORD96)
276
control_reg |= GML_DOUBLE_SPEED_MODE;
277
else
278
control_reg &= ~GML_DOUBLE_SPEED_MODE;
279
break;
280
case ECHO_CLOCK_ADAT:
281
if (chip->digital_mode != DIGITAL_MODE_ADAT)
282
return -EAGAIN;
283
control_reg |= GML_ADAT_CLOCK;
284
control_reg &= ~GML_DOUBLE_SPEED_MODE;
285
break;
286
default:
287
dev_err(chip->card->dev,
288
"Input clock 0x%x not supported for Layla24\n", clock);
289
return -EINVAL;
290
}
291
292
chip->input_clock = clock;
293
return write_control_reg(chip, control_reg, true);
294
}
295
296
297
298
/* Depending on what digital mode you want, Layla24 needs different ASICs
299
loaded. This function checks the ASIC needed for the new mode and sees
300
if it matches the one already loaded. */
301
static int switch_asic(struct echoaudio *chip, short asic)
302
{
303
s8 *monitors;
304
305
/* Check to see if this is already loaded */
306
if (asic != chip->asic_code) {
307
monitors = kmemdup(chip->comm_page->monitors,
308
MONITOR_ARRAY_SIZE, GFP_KERNEL);
309
if (! monitors)
310
return -ENOMEM;
311
312
memset(chip->comm_page->monitors, ECHOGAIN_MUTED,
313
MONITOR_ARRAY_SIZE);
314
315
/* Load the desired ASIC */
316
if (load_asic_generic(chip, DSP_FNC_LOAD_LAYLA24_EXTERNAL_ASIC,
317
asic) < 0) {
318
memcpy(chip->comm_page->monitors, monitors,
319
MONITOR_ARRAY_SIZE);
320
kfree(monitors);
321
return -EIO;
322
}
323
chip->asic_code = asic;
324
memcpy(chip->comm_page->monitors, monitors, MONITOR_ARRAY_SIZE);
325
kfree(monitors);
326
}
327
328
return 0;
329
}
330
331
332
333
static int dsp_set_digital_mode(struct echoaudio *chip, u8 mode)
334
{
335
u32 control_reg;
336
int err, incompatible_clock;
337
short asic;
338
339
/* Set clock to "internal" if it's not compatible with the new mode */
340
incompatible_clock = false;
341
switch (mode) {
342
case DIGITAL_MODE_SPDIF_OPTICAL:
343
case DIGITAL_MODE_SPDIF_RCA:
344
if (chip->input_clock == ECHO_CLOCK_ADAT)
345
incompatible_clock = true;
346
asic = FW_LAYLA24_2S_ASIC;
347
break;
348
case DIGITAL_MODE_ADAT:
349
if (chip->input_clock == ECHO_CLOCK_SPDIF)
350
incompatible_clock = true;
351
asic = FW_LAYLA24_2A_ASIC;
352
break;
353
default:
354
dev_err(chip->card->dev,
355
"Digital mode not supported: %d\n", mode);
356
return -EINVAL;
357
}
358
359
if (incompatible_clock) { /* Switch to 48KHz, internal */
360
chip->sample_rate = 48000;
361
spin_lock_irq(&chip->lock);
362
set_input_clock(chip, ECHO_CLOCK_INTERNAL);
363
spin_unlock_irq(&chip->lock);
364
}
365
366
/* switch_asic() can sleep */
367
if (switch_asic(chip, asic) < 0)
368
return -EIO;
369
370
spin_lock_irq(&chip->lock);
371
372
/* Tweak the control register */
373
control_reg = le32_to_cpu(chip->comm_page->control_register);
374
control_reg &= GML_DIGITAL_MODE_CLEAR_MASK;
375
376
switch (mode) {
377
case DIGITAL_MODE_SPDIF_OPTICAL:
378
control_reg |= GML_SPDIF_OPTICAL_MODE;
379
break;
380
case DIGITAL_MODE_SPDIF_RCA:
381
/* GML_SPDIF_OPTICAL_MODE bit cleared */
382
break;
383
case DIGITAL_MODE_ADAT:
384
control_reg |= GML_ADAT_MODE;
385
control_reg &= ~GML_DOUBLE_SPEED_MODE;
386
break;
387
}
388
389
err = write_control_reg(chip, control_reg, true);
390
spin_unlock_irq(&chip->lock);
391
if (err < 0)
392
return err;
393
chip->digital_mode = mode;
394
395
dev_dbg(chip->card->dev, "set_digital_mode to %d\n", mode);
396
return incompatible_clock;
397
}
398
399