Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
torvalds
GitHub Repository: torvalds/linux
Path: blob/master/sound/pci/echoaudio/gina24_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) != GINA24))
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_ESYNC | ECHO_CLOCK_BIT_ESYNC96 |
60
ECHO_CLOCK_BIT_ADAT;
61
62
/* Gina24 comes in both '301 and '361 flavors */
63
if (chip->device_id == DEVICE_ID_56361) {
64
chip->dsp_code_to_load = FW_GINA24_361_DSP;
65
chip->digital_modes =
66
ECHOCAPS_HAS_DIGITAL_MODE_SPDIF_RCA |
67
ECHOCAPS_HAS_DIGITAL_MODE_SPDIF_OPTICAL |
68
ECHOCAPS_HAS_DIGITAL_MODE_ADAT;
69
} else {
70
chip->dsp_code_to_load = FW_GINA24_301_DSP;
71
chip->digital_modes =
72
ECHOCAPS_HAS_DIGITAL_MODE_SPDIF_RCA |
73
ECHOCAPS_HAS_DIGITAL_MODE_SPDIF_OPTICAL |
74
ECHOCAPS_HAS_DIGITAL_MODE_ADAT |
75
ECHOCAPS_HAS_DIGITAL_MODE_SPDIF_CDROM;
76
}
77
78
err = load_firmware(chip);
79
if (err < 0)
80
return err;
81
chip->bad_board = false;
82
83
return err;
84
}
85
86
87
88
static int set_mixer_defaults(struct echoaudio *chip)
89
{
90
chip->digital_mode = DIGITAL_MODE_SPDIF_RCA;
91
chip->professional_spdif = false;
92
chip->digital_in_automute = true;
93
return init_line_levels(chip);
94
}
95
96
97
98
static u32 detect_input_clocks(const struct echoaudio *chip)
99
{
100
u32 clocks_from_dsp, clock_bits;
101
102
/* Map the DSP clock detect bits to the generic driver clock
103
detect bits */
104
clocks_from_dsp = le32_to_cpu(chip->comm_page->status_clocks);
105
106
clock_bits = ECHO_CLOCK_BIT_INTERNAL;
107
108
if (clocks_from_dsp & GML_CLOCK_DETECT_BIT_SPDIF)
109
clock_bits |= ECHO_CLOCK_BIT_SPDIF;
110
111
if (clocks_from_dsp & GML_CLOCK_DETECT_BIT_ADAT)
112
clock_bits |= ECHO_CLOCK_BIT_ADAT;
113
114
if (clocks_from_dsp & GML_CLOCK_DETECT_BIT_ESYNC)
115
clock_bits |= ECHO_CLOCK_BIT_ESYNC | ECHO_CLOCK_BIT_ESYNC96;
116
117
return clock_bits;
118
}
119
120
121
122
/* Gina24 has an ASIC on the PCI card which must be loaded for anything
123
interesting to happen. */
124
static int load_asic(struct echoaudio *chip)
125
{
126
u32 control_reg;
127
int err;
128
short asic;
129
130
if (chip->asic_loaded)
131
return 1;
132
133
/* Give the DSP a few milliseconds to settle down */
134
mdelay(10);
135
136
/* Pick the correct ASIC for '301 or '361 Gina24 */
137
if (chip->device_id == DEVICE_ID_56361)
138
asic = FW_GINA24_361_ASIC;
139
else
140
asic = FW_GINA24_301_ASIC;
141
142
err = load_asic_generic(chip, DSP_FNC_LOAD_GINA24_ASIC, asic);
143
if (err < 0)
144
return err;
145
146
chip->asic_code = asic;
147
148
/* Now give the new ASIC a little time to set up */
149
mdelay(10);
150
/* See if it worked */
151
err = check_asic_status(chip);
152
153
/* Set up the control register if the load succeeded -
154
48 kHz, internal clock, S/PDIF RCA mode */
155
if (!err) {
156
control_reg = GML_CONVERTER_ENABLE | GML_48KHZ;
157
err = write_control_reg(chip, control_reg, true);
158
}
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
dev_warn(chip->card->dev,
175
"Cannot set sample rate - 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
dev_err(chip->card->dev,
221
"set_sample_rate: %d invalid!\n", rate);
222
return -EINVAL;
223
}
224
225
control_reg |= clock;
226
227
chip->comm_page->sample_rate = cpu_to_le32(rate); /* ignored by the DSP */
228
chip->sample_rate = rate;
229
dev_dbg(chip->card->dev, "set_sample_rate: %d clock %d\n", rate, clock);
230
231
return write_control_reg(chip, control_reg, false);
232
}
233
234
235
236
static int set_input_clock(struct echoaudio *chip, u16 clock)
237
{
238
u32 control_reg, clocks_from_dsp;
239
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
chip->input_clock = ECHO_CLOCK_INTERNAL;
249
return set_sample_rate(chip, chip->sample_rate);
250
case ECHO_CLOCK_SPDIF:
251
if (chip->digital_mode == DIGITAL_MODE_ADAT)
252
return -EAGAIN;
253
control_reg |= GML_SPDIF_CLOCK;
254
if (clocks_from_dsp & GML_CLOCK_DETECT_BIT_SPDIF96)
255
control_reg |= GML_DOUBLE_SPEED_MODE;
256
else
257
control_reg &= ~GML_DOUBLE_SPEED_MODE;
258
break;
259
case ECHO_CLOCK_ADAT:
260
if (chip->digital_mode != DIGITAL_MODE_ADAT)
261
return -EAGAIN;
262
control_reg |= GML_ADAT_CLOCK;
263
control_reg &= ~GML_DOUBLE_SPEED_MODE;
264
break;
265
case ECHO_CLOCK_ESYNC:
266
control_reg |= GML_ESYNC_CLOCK;
267
control_reg &= ~GML_DOUBLE_SPEED_MODE;
268
break;
269
case ECHO_CLOCK_ESYNC96:
270
control_reg |= GML_ESYNC_CLOCK | GML_DOUBLE_SPEED_MODE;
271
break;
272
default:
273
dev_err(chip->card->dev,
274
"Input clock 0x%x not supported for Gina24\n", clock);
275
return -EINVAL;
276
}
277
278
chip->input_clock = clock;
279
return write_control_reg(chip, control_reg, true);
280
}
281
282
283
284
static int dsp_set_digital_mode(struct echoaudio *chip, u8 mode)
285
{
286
u32 control_reg;
287
int err, incompatible_clock;
288
289
/* Set clock to "internal" if it's not compatible with the new mode */
290
incompatible_clock = false;
291
switch (mode) {
292
case DIGITAL_MODE_SPDIF_OPTICAL:
293
case DIGITAL_MODE_SPDIF_CDROM:
294
case DIGITAL_MODE_SPDIF_RCA:
295
if (chip->input_clock == ECHO_CLOCK_ADAT)
296
incompatible_clock = true;
297
break;
298
case DIGITAL_MODE_ADAT:
299
if (chip->input_clock == ECHO_CLOCK_SPDIF)
300
incompatible_clock = true;
301
break;
302
default:
303
dev_err(chip->card->dev,
304
"Digital mode not supported: %d\n", mode);
305
return -EINVAL;
306
}
307
308
spin_lock_irq(&chip->lock);
309
310
if (incompatible_clock) { /* Switch to 48KHz, internal */
311
chip->sample_rate = 48000;
312
set_input_clock(chip, ECHO_CLOCK_INTERNAL);
313
}
314
315
/* Clear the current digital mode */
316
control_reg = le32_to_cpu(chip->comm_page->control_register);
317
control_reg &= GML_DIGITAL_MODE_CLEAR_MASK;
318
319
/* Tweak the control reg */
320
switch (mode) {
321
case DIGITAL_MODE_SPDIF_OPTICAL:
322
control_reg |= GML_SPDIF_OPTICAL_MODE;
323
break;
324
case DIGITAL_MODE_SPDIF_CDROM:
325
/* '361 Gina24 cards do not have the S/PDIF CD-ROM mode */
326
if (chip->device_id == DEVICE_ID_56301)
327
control_reg |= GML_SPDIF_CDROM_MODE;
328
break;
329
case DIGITAL_MODE_SPDIF_RCA:
330
/* GML_SPDIF_OPTICAL_MODE bit cleared */
331
break;
332
case DIGITAL_MODE_ADAT:
333
control_reg |= GML_ADAT_MODE;
334
control_reg &= ~GML_DOUBLE_SPEED_MODE;
335
break;
336
}
337
338
err = write_control_reg(chip, control_reg, true);
339
spin_unlock_irq(&chip->lock);
340
if (err < 0)
341
return err;
342
chip->digital_mode = mode;
343
344
dev_dbg(chip->card->dev,
345
"set_digital_mode to %d\n", chip->digital_mode);
346
return incompatible_clock;
347
}
348
349