Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
torvalds
GitHub Repository: torvalds/linux
Path: blob/master/sound/pci/echoaudio/mona_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
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 <[email protected]>
28
29
****************************************************************************/
30
31
32
static int write_control_reg(struct echoaudio *chip, u32 value, char force);
33
static int set_input_clock(struct echoaudio *chip, u16 clock);
34
static int set_professional_spdif(struct echoaudio *chip, char prof);
35
static int set_digital_mode(struct echoaudio *chip, u8 mode);
36
static int load_asic_generic(struct echoaudio *chip, u32 cmd, short asic);
37
static int check_asic_status(struct echoaudio *chip);
38
39
40
static int init_hw(struct echoaudio *chip, u16 device_id, u16 subdevice_id)
41
{
42
int err;
43
44
if (snd_BUG_ON((subdevice_id & 0xfff0) != MONA))
45
return -ENODEV;
46
47
err = init_dsp_comm_page(chip);
48
if (err) {
49
dev_err(chip->card->dev,
50
"init_hw - could not initialize DSP comm page\n");
51
return err;
52
}
53
54
chip->device_id = device_id;
55
chip->subdevice_id = subdevice_id;
56
chip->bad_board = true;
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
/* Mona comes in both '301 and '361 flavors */
66
if (chip->device_id == DEVICE_ID_56361)
67
chip->dsp_code_to_load = FW_MONA_361_DSP;
68
else
69
chip->dsp_code_to_load = FW_MONA_301_DSP;
70
71
err = load_firmware(chip);
72
if (err < 0)
73
return err;
74
chip->bad_board = false;
75
76
return err;
77
}
78
79
80
81
static int set_mixer_defaults(struct echoaudio *chip)
82
{
83
chip->digital_mode = DIGITAL_MODE_SPDIF_RCA;
84
chip->professional_spdif = false;
85
chip->digital_in_automute = true;
86
return init_line_levels(chip);
87
}
88
89
90
91
static 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;
116
both need to be loaded. */
117
static int load_asic(struct echoaudio *chip)
118
{
119
u32 control_reg;
120
int err;
121
short 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 = FW_MONA_361_1_ASIC48;
130
else
131
asic = 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
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
162
loaded. This function checks the ASIC needed for the new mode and sees
163
if it matches the one already loaded. */
164
static int switch_asic(struct echoaudio *chip, char double_speed)
165
{
166
int err;
167
short asic;
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 = FW_MONA_361_1_ASIC96;
175
else
176
asic = FW_MONA_361_1_ASIC48;
177
} else {
178
if (double_speed)
179
asic = FW_MONA_301_1_ASIC96;
180
else
181
asic = 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
198
static int set_sample_rate(struct echoaudio *chip, u32 rate)
199
{
200
u32 control_reg, clock;
201
short asic;
202
char force_write;
203
204
/* Only set the clock for internal mode. */
205
if (chip->input_clock != ECHO_CLOCK_INTERNAL) {
206
dev_dbg(chip->card->dev,
207
"Cannot set sample rate - 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 = FW_MONA_361_1_ASIC96;
220
else
221
asic = FW_MONA_301_1_ASIC96;
222
} else {
223
if (chip->device_id == DEVICE_ID_56361)
224
asic = FW_MONA_361_1_ASIC48;
225
else
226
asic = 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
dev_err(chip->card->dev,
284
"set_sample_rate: %d invalid!\n", rate);
285
return -EINVAL;
286
}
287
288
control_reg |= clock;
289
290
chip->comm_page->sample_rate = cpu_to_le32(rate); /* ignored by the DSP */
291
chip->sample_rate = rate;
292
dev_dbg(chip->card->dev,
293
"set_sample_rate: %d clock %d\n", rate, clock);
294
295
return write_control_reg(chip, control_reg, force_write);
296
}
297
298
299
300
static int set_input_clock(struct echoaudio *chip, u16 clock)
301
{
302
u32 control_reg, clocks_from_dsp;
303
int err;
304
305
/* Mask off the clock select bits */
306
control_reg = le32_to_cpu(chip->comm_page->control_register) &
307
GML_CLOCK_CLEAR_MASK;
308
clocks_from_dsp = le32_to_cpu(chip->comm_page->status_clocks);
309
310
switch (clock) {
311
case ECHO_CLOCK_INTERNAL:
312
chip->input_clock = ECHO_CLOCK_INTERNAL;
313
return set_sample_rate(chip, chip->sample_rate);
314
case ECHO_CLOCK_SPDIF:
315
if (chip->digital_mode == DIGITAL_MODE_ADAT)
316
return -EAGAIN;
317
spin_unlock_irq(&chip->lock);
318
err = switch_asic(chip, clocks_from_dsp &
319
GML_CLOCK_DETECT_BIT_SPDIF96);
320
spin_lock_irq(&chip->lock);
321
if (err < 0)
322
return err;
323
control_reg |= GML_SPDIF_CLOCK;
324
if (clocks_from_dsp & GML_CLOCK_DETECT_BIT_SPDIF96)
325
control_reg |= GML_DOUBLE_SPEED_MODE;
326
else
327
control_reg &= ~GML_DOUBLE_SPEED_MODE;
328
break;
329
case ECHO_CLOCK_WORD:
330
spin_unlock_irq(&chip->lock);
331
err = switch_asic(chip, clocks_from_dsp &
332
GML_CLOCK_DETECT_BIT_WORD96);
333
spin_lock_irq(&chip->lock);
334
if (err < 0)
335
return err;
336
control_reg |= GML_WORD_CLOCK;
337
if (clocks_from_dsp & GML_CLOCK_DETECT_BIT_WORD96)
338
control_reg |= GML_DOUBLE_SPEED_MODE;
339
else
340
control_reg &= ~GML_DOUBLE_SPEED_MODE;
341
break;
342
case ECHO_CLOCK_ADAT:
343
dev_dbg(chip->card->dev, "Set Mona clock to ADAT\n");
344
if (chip->digital_mode != DIGITAL_MODE_ADAT)
345
return -EAGAIN;
346
control_reg |= GML_ADAT_CLOCK;
347
control_reg &= ~GML_DOUBLE_SPEED_MODE;
348
break;
349
default:
350
dev_err(chip->card->dev,
351
"Input clock 0x%x not supported for Mona\n", clock);
352
return -EINVAL;
353
}
354
355
chip->input_clock = clock;
356
return write_control_reg(chip, control_reg, true);
357
}
358
359
360
361
static int dsp_set_digital_mode(struct echoaudio *chip, u8 mode)
362
{
363
u32 control_reg;
364
int err, incompatible_clock;
365
366
/* Set clock to "internal" if it's not compatible with the new mode */
367
incompatible_clock = false;
368
switch (mode) {
369
case DIGITAL_MODE_SPDIF_OPTICAL:
370
case DIGITAL_MODE_SPDIF_RCA:
371
if (chip->input_clock == ECHO_CLOCK_ADAT)
372
incompatible_clock = true;
373
break;
374
case DIGITAL_MODE_ADAT:
375
if (chip->input_clock == ECHO_CLOCK_SPDIF)
376
incompatible_clock = true;
377
break;
378
default:
379
dev_err(chip->card->dev,
380
"Digital mode not supported: %d\n", mode);
381
return -EINVAL;
382
}
383
384
spin_lock_irq(&chip->lock);
385
386
if (incompatible_clock) { /* Switch to 48KHz, internal */
387
chip->sample_rate = 48000;
388
set_input_clock(chip, ECHO_CLOCK_INTERNAL);
389
}
390
391
/* Clear the current digital mode */
392
control_reg = le32_to_cpu(chip->comm_page->control_register);
393
control_reg &= GML_DIGITAL_MODE_CLEAR_MASK;
394
395
/* Tweak the control reg */
396
switch (mode) {
397
case DIGITAL_MODE_SPDIF_OPTICAL:
398
control_reg |= GML_SPDIF_OPTICAL_MODE;
399
break;
400
case DIGITAL_MODE_SPDIF_RCA:
401
/* GML_SPDIF_OPTICAL_MODE bit cleared */
402
break;
403
case DIGITAL_MODE_ADAT:
404
/* If the current ASIC is the 96KHz ASIC, switch the ASIC
405
and set to 48 KHz */
406
if (chip->asic_code == FW_MONA_361_1_ASIC96 ||
407
chip->asic_code == FW_MONA_301_1_ASIC96) {
408
set_sample_rate(chip, 48000);
409
}
410
control_reg |= GML_ADAT_MODE;
411
control_reg &= ~GML_DOUBLE_SPEED_MODE;
412
break;
413
}
414
415
err = write_control_reg(chip, control_reg, false);
416
spin_unlock_irq(&chip->lock);
417
if (err < 0)
418
return err;
419
chip->digital_mode = mode;
420
421
dev_dbg(chip->card->dev, "set_digital_mode to %d\n", mode);
422
return incompatible_clock;
423
}
424
425