Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
awilliam
GitHub Repository: awilliam/linux-vfio
Path: blob/master/sound/pci/echoaudio/gina24_dsp.c
10818 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
DE_INIT(("init_hw() - Gina24\n"));
45
if (snd_BUG_ON((subdevice_id & 0xfff0) != GINA24))
46
return -ENODEV;
47
48
if ((err = init_dsp_comm_page(chip))) {
49
DE_INIT(("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->input_clock_types =
57
ECHO_CLOCK_BIT_INTERNAL | ECHO_CLOCK_BIT_SPDIF |
58
ECHO_CLOCK_BIT_ESYNC | ECHO_CLOCK_BIT_ESYNC96 |
59
ECHO_CLOCK_BIT_ADAT;
60
61
/* Gina24 comes in both '301 and '361 flavors */
62
if (chip->device_id == DEVICE_ID_56361) {
63
chip->dsp_code_to_load = FW_GINA24_361_DSP;
64
chip->digital_modes =
65
ECHOCAPS_HAS_DIGITAL_MODE_SPDIF_RCA |
66
ECHOCAPS_HAS_DIGITAL_MODE_SPDIF_OPTICAL |
67
ECHOCAPS_HAS_DIGITAL_MODE_ADAT;
68
} else {
69
chip->dsp_code_to_load = FW_GINA24_301_DSP;
70
chip->digital_modes =
71
ECHOCAPS_HAS_DIGITAL_MODE_SPDIF_RCA |
72
ECHOCAPS_HAS_DIGITAL_MODE_SPDIF_OPTICAL |
73
ECHOCAPS_HAS_DIGITAL_MODE_ADAT |
74
ECHOCAPS_HAS_DIGITAL_MODE_SPDIF_CDROM;
75
}
76
77
if ((err = load_firmware(chip)) < 0)
78
return err;
79
chip->bad_board = FALSE;
80
81
DE_INIT(("init_hw done\n"));
82
return err;
83
}
84
85
86
87
static int set_mixer_defaults(struct echoaudio *chip)
88
{
89
chip->digital_mode = DIGITAL_MODE_SPDIF_RCA;
90
chip->professional_spdif = FALSE;
91
chip->digital_in_automute = TRUE;
92
return init_line_levels(chip);
93
}
94
95
96
97
static u32 detect_input_clocks(const struct echoaudio *chip)
98
{
99
u32 clocks_from_dsp, clock_bits;
100
101
/* Map the DSP clock detect bits to the generic driver clock
102
detect bits */
103
clocks_from_dsp = le32_to_cpu(chip->comm_page->status_clocks);
104
105
clock_bits = ECHO_CLOCK_BIT_INTERNAL;
106
107
if (clocks_from_dsp & GML_CLOCK_DETECT_BIT_SPDIF)
108
clock_bits |= ECHO_CLOCK_BIT_SPDIF;
109
110
if (clocks_from_dsp & GML_CLOCK_DETECT_BIT_ADAT)
111
clock_bits |= ECHO_CLOCK_BIT_ADAT;
112
113
if (clocks_from_dsp & GML_CLOCK_DETECT_BIT_ESYNC)
114
clock_bits |= ECHO_CLOCK_BIT_ESYNC | ECHO_CLOCK_BIT_ESYNC96;
115
116
return clock_bits;
117
}
118
119
120
121
/* Gina24 has an ASIC on the PCI card which must be loaded for anything
122
interesting to happen. */
123
static int load_asic(struct echoaudio *chip)
124
{
125
u32 control_reg;
126
int err;
127
short asic;
128
129
if (chip->asic_loaded)
130
return 1;
131
132
/* Give the DSP a few milliseconds to settle down */
133
mdelay(10);
134
135
/* Pick the correct ASIC for '301 or '361 Gina24 */
136
if (chip->device_id == DEVICE_ID_56361)
137
asic = FW_GINA24_361_ASIC;
138
else
139
asic = FW_GINA24_301_ASIC;
140
141
err = load_asic_generic(chip, DSP_FNC_LOAD_GINA24_ASIC, asic);
142
if (err < 0)
143
return err;
144
145
chip->asic_code = asic;
146
147
/* Now give the new ASIC a little time to set up */
148
mdelay(10);
149
/* See if it worked */
150
err = check_asic_status(chip);
151
152
/* Set up the control register if the load succeeded -
153
48 kHz, internal clock, S/PDIF RCA mode */
154
if (!err) {
155
control_reg = GML_CONVERTER_ENABLE | GML_48KHZ;
156
err = write_control_reg(chip, control_reg, TRUE);
157
}
158
DE_INIT(("load_asic() done\n"));
159
return err;
160
}
161
162
163
164
static int set_sample_rate(struct echoaudio *chip, u32 rate)
165
{
166
u32 control_reg, clock;
167
168
if (snd_BUG_ON(rate >= 50000 &&
169
chip->digital_mode == DIGITAL_MODE_ADAT))
170
return -EINVAL;
171
172
/* Only set the clock for internal mode. */
173
if (chip->input_clock != ECHO_CLOCK_INTERNAL) {
174
DE_ACT(("set_sample_rate: Cannot set sample rate - "
175
"clock not set to CLK_CLOCKININTERNAL\n"));
176
/* Save the rate anyhow */
177
chip->comm_page->sample_rate = cpu_to_le32(rate);
178
chip->sample_rate = rate;
179
return 0;
180
}
181
182
clock = 0;
183
184
control_reg = le32_to_cpu(chip->comm_page->control_register);
185
control_reg &= GML_CLOCK_CLEAR_MASK & GML_SPDIF_RATE_CLEAR_MASK;
186
187
switch (rate) {
188
case 96000:
189
clock = GML_96KHZ;
190
break;
191
case 88200:
192
clock = GML_88KHZ;
193
break;
194
case 48000:
195
clock = GML_48KHZ | GML_SPDIF_SAMPLE_RATE1;
196
break;
197
case 44100:
198
clock = GML_44KHZ;
199
/* Professional mode ? */
200
if (control_reg & GML_SPDIF_PRO_MODE)
201
clock |= GML_SPDIF_SAMPLE_RATE0;
202
break;
203
case 32000:
204
clock = GML_32KHZ | GML_SPDIF_SAMPLE_RATE0 |
205
GML_SPDIF_SAMPLE_RATE1;
206
break;
207
case 22050:
208
clock = GML_22KHZ;
209
break;
210
case 16000:
211
clock = GML_16KHZ;
212
break;
213
case 11025:
214
clock = GML_11KHZ;
215
break;
216
case 8000:
217
clock = GML_8KHZ;
218
break;
219
default:
220
DE_ACT(("set_sample_rate: %d invalid!\n", rate));
221
return -EINVAL;
222
}
223
224
control_reg |= clock;
225
226
chip->comm_page->sample_rate = cpu_to_le32(rate); /* ignored by the DSP */
227
chip->sample_rate = rate;
228
DE_ACT(("set_sample_rate: %d clock %d\n", rate, clock));
229
230
return write_control_reg(chip, control_reg, FALSE);
231
}
232
233
234
235
static int set_input_clock(struct echoaudio *chip, u16 clock)
236
{
237
u32 control_reg, clocks_from_dsp;
238
239
DE_ACT(("set_input_clock:\n"));
240
241
/* Mask off the clock select bits */
242
control_reg = le32_to_cpu(chip->comm_page->control_register) &
243
GML_CLOCK_CLEAR_MASK;
244
clocks_from_dsp = le32_to_cpu(chip->comm_page->status_clocks);
245
246
switch (clock) {
247
case ECHO_CLOCK_INTERNAL:
248
DE_ACT(("Set Gina24 clock to INTERNAL\n"));
249
chip->input_clock = ECHO_CLOCK_INTERNAL;
250
return set_sample_rate(chip, chip->sample_rate);
251
case ECHO_CLOCK_SPDIF:
252
if (chip->digital_mode == DIGITAL_MODE_ADAT)
253
return -EAGAIN;
254
DE_ACT(("Set Gina24 clock to SPDIF\n"));
255
control_reg |= GML_SPDIF_CLOCK;
256
if (clocks_from_dsp & GML_CLOCK_DETECT_BIT_SPDIF96)
257
control_reg |= GML_DOUBLE_SPEED_MODE;
258
else
259
control_reg &= ~GML_DOUBLE_SPEED_MODE;
260
break;
261
case ECHO_CLOCK_ADAT:
262
if (chip->digital_mode != DIGITAL_MODE_ADAT)
263
return -EAGAIN;
264
DE_ACT(("Set Gina24 clock to ADAT\n"));
265
control_reg |= GML_ADAT_CLOCK;
266
control_reg &= ~GML_DOUBLE_SPEED_MODE;
267
break;
268
case ECHO_CLOCK_ESYNC:
269
DE_ACT(("Set Gina24 clock to ESYNC\n"));
270
control_reg |= GML_ESYNC_CLOCK;
271
control_reg &= ~GML_DOUBLE_SPEED_MODE;
272
break;
273
case ECHO_CLOCK_ESYNC96:
274
DE_ACT(("Set Gina24 clock to ESYNC96\n"));
275
control_reg |= GML_ESYNC_CLOCK | GML_DOUBLE_SPEED_MODE;
276
break;
277
default:
278
DE_ACT(("Input clock 0x%x not supported for Gina24\n", clock));
279
return -EINVAL;
280
}
281
282
chip->input_clock = clock;
283
return write_control_reg(chip, control_reg, TRUE);
284
}
285
286
287
288
static int dsp_set_digital_mode(struct echoaudio *chip, u8 mode)
289
{
290
u32 control_reg;
291
int err, incompatible_clock;
292
293
/* Set clock to "internal" if it's not compatible with the new mode */
294
incompatible_clock = FALSE;
295
switch (mode) {
296
case DIGITAL_MODE_SPDIF_OPTICAL:
297
case DIGITAL_MODE_SPDIF_CDROM:
298
case DIGITAL_MODE_SPDIF_RCA:
299
if (chip->input_clock == ECHO_CLOCK_ADAT)
300
incompatible_clock = TRUE;
301
break;
302
case DIGITAL_MODE_ADAT:
303
if (chip->input_clock == ECHO_CLOCK_SPDIF)
304
incompatible_clock = TRUE;
305
break;
306
default:
307
DE_ACT(("Digital mode not supported: %d\n", mode));
308
return -EINVAL;
309
}
310
311
spin_lock_irq(&chip->lock);
312
313
if (incompatible_clock) { /* Switch to 48KHz, internal */
314
chip->sample_rate = 48000;
315
set_input_clock(chip, ECHO_CLOCK_INTERNAL);
316
}
317
318
/* Clear the current digital mode */
319
control_reg = le32_to_cpu(chip->comm_page->control_register);
320
control_reg &= GML_DIGITAL_MODE_CLEAR_MASK;
321
322
/* Tweak the control reg */
323
switch (mode) {
324
case DIGITAL_MODE_SPDIF_OPTICAL:
325
control_reg |= GML_SPDIF_OPTICAL_MODE;
326
break;
327
case DIGITAL_MODE_SPDIF_CDROM:
328
/* '361 Gina24 cards do not have the S/PDIF CD-ROM mode */
329
if (chip->device_id == DEVICE_ID_56301)
330
control_reg |= GML_SPDIF_CDROM_MODE;
331
break;
332
case DIGITAL_MODE_SPDIF_RCA:
333
/* GML_SPDIF_OPTICAL_MODE bit cleared */
334
break;
335
case DIGITAL_MODE_ADAT:
336
control_reg |= GML_ADAT_MODE;
337
control_reg &= ~GML_DOUBLE_SPEED_MODE;
338
break;
339
}
340
341
err = write_control_reg(chip, control_reg, TRUE);
342
spin_unlock_irq(&chip->lock);
343
if (err < 0)
344
return err;
345
chip->digital_mode = mode;
346
347
DE_ACT(("set_digital_mode to %d\n", chip->digital_mode));
348
return incompatible_clock;
349
}
350
351