aboutsummaryrefslogtreecommitdiffstats
path: root/sound/pci/echoaudio/gina24_dsp.c
diff options
context:
space:
mode:
Diffstat (limited to 'sound/pci/echoaudio/gina24_dsp.c')
-rw-r--r--sound/pci/echoaudio/gina24_dsp.c346
1 files changed, 346 insertions, 0 deletions
diff --git a/sound/pci/echoaudio/gina24_dsp.c b/sound/pci/echoaudio/gina24_dsp.c
new file mode 100644
index 000000000000..144fc567becf
--- /dev/null
+++ b/sound/pci/echoaudio/gina24_dsp.c
@@ -0,0 +1,346 @@
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 <pochini@shiny.it>
28
29****************************************************************************/
30
31
32static int write_control_reg(struct echoaudio *chip, u32 value, char force);
33static int set_input_clock(struct echoaudio *chip, u16 clock);
34static int set_professional_spdif(struct echoaudio *chip, char prof);
35static int set_digital_mode(struct echoaudio *chip, u8 mode);
36static int load_asic_generic(struct echoaudio *chip, u32 cmd,
37 const struct firmware *asic);
38static int check_asic_status(struct echoaudio *chip);
39
40
41static int init_hw(struct echoaudio *chip, u16 device_id, u16 subdevice_id)
42{
43 int err;
44
45 DE_INIT(("init_hw() - Gina24\n"));
46 snd_assert((subdevice_id & 0xfff0) == GINA24, 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 chip->professional_spdif = FALSE;
61 chip->digital_in_automute = TRUE;
62 chip->digital_mode = DIGITAL_MODE_SPDIF_RCA;
63
64 /* Gina24 comes in both '301 and '361 flavors */
65 if (chip->device_id == DEVICE_ID_56361) {
66 chip->dsp_code_to_load = &card_fw[FW_GINA24_361_DSP];
67 chip->digital_modes =
68 ECHOCAPS_HAS_DIGITAL_MODE_SPDIF_RCA |
69 ECHOCAPS_HAS_DIGITAL_MODE_SPDIF_OPTICAL |
70 ECHOCAPS_HAS_DIGITAL_MODE_ADAT;
71 } else {
72 chip->dsp_code_to_load = &card_fw[FW_GINA24_301_DSP];
73 chip->digital_modes =
74 ECHOCAPS_HAS_DIGITAL_MODE_SPDIF_RCA |
75 ECHOCAPS_HAS_DIGITAL_MODE_SPDIF_OPTICAL |
76 ECHOCAPS_HAS_DIGITAL_MODE_ADAT |
77 ECHOCAPS_HAS_DIGITAL_MODE_SPDIF_CDROM;
78 }
79
80 if ((err = load_firmware(chip)) < 0)
81 return err;
82 chip->bad_board = FALSE;
83
84 if ((err = init_line_levels(chip)) < 0)
85 return err;
86 err = set_digital_mode(chip, DIGITAL_MODE_SPDIF_RCA);
87 snd_assert(err >= 0, return err);
88 err = set_professional_spdif(chip, TRUE);
89
90 DE_INIT(("init_hw done\n"));
91 return err;
92}
93
94
95
96static u32 detect_input_clocks(const struct echoaudio *chip)
97{
98 u32 clocks_from_dsp, clock_bits;
99
100 /* Map the DSP clock detect bits to the generic driver clock
101 detect bits */
102 clocks_from_dsp = le32_to_cpu(chip->comm_page->status_clocks);
103
104 clock_bits = ECHO_CLOCK_BIT_INTERNAL;
105
106 if (clocks_from_dsp & GML_CLOCK_DETECT_BIT_SPDIF)
107 clock_bits |= ECHO_CLOCK_BIT_SPDIF;
108
109 if (clocks_from_dsp & GML_CLOCK_DETECT_BIT_ADAT)
110 clock_bits |= ECHO_CLOCK_BIT_ADAT;
111
112 if (clocks_from_dsp & GML_CLOCK_DETECT_BIT_ESYNC)
113 clock_bits |= ECHO_CLOCK_BIT_ESYNC | ECHO_CLOCK_BIT_ESYNC96;
114
115 return clock_bits;
116}
117
118
119
120/* Gina24 has an ASIC on the PCI card which must be loaded for anything
121interesting to happen. */
122static int load_asic(struct echoaudio *chip)
123{
124 u32 control_reg;
125 int err;
126 const struct firmware *fw;
127
128 if (chip->asic_loaded)
129 return 1;
130
131 /* Give the DSP a few milliseconds to settle down */
132 mdelay(10);
133
134 /* Pick the correct ASIC for '301 or '361 Gina24 */
135 if (chip->device_id == DEVICE_ID_56361)
136 fw = &card_fw[FW_GINA24_361_ASIC];
137 else
138 fw = &card_fw[FW_GINA24_301_ASIC];
139
140 if ((err = load_asic_generic(chip, DSP_FNC_LOAD_GINA24_ASIC, fw)) < 0)
141 return err;
142
143 chip->asic_code = fw;
144
145 /* Now give the new ASIC a little time to set up */
146 mdelay(10);
147 /* See if it worked */
148 err = check_asic_status(chip);
149
150 /* Set up the control register if the load succeeded -
151 48 kHz, internal clock, S/PDIF RCA mode */
152 if (!err) {
153 control_reg = GML_CONVERTER_ENABLE | GML_48KHZ;
154 err = write_control_reg(chip, control_reg, TRUE);
155 }
156 DE_INIT(("load_asic() done\n"));
157 return err;
158}
159
160
161
162static int set_sample_rate(struct echoaudio *chip, u32 rate)
163{
164 u32 control_reg, clock;
165
166 snd_assert(rate < 50000 || chip->digital_mode != DIGITAL_MODE_ADAT,
167 return -EINVAL);
168
169 /* Only set the clock for internal mode. */
170 if (chip->input_clock != ECHO_CLOCK_INTERNAL) {
171 DE_ACT(("set_sample_rate: Cannot set sample rate - "
172 "clock not set to CLK_CLOCKININTERNAL\n"));
173 /* Save the rate anyhow */
174 chip->comm_page->sample_rate = cpu_to_le32(rate);
175 chip->sample_rate = rate;
176 return 0;
177 }
178
179 clock = 0;
180
181 control_reg = le32_to_cpu(chip->comm_page->control_register);
182 control_reg &= GML_CLOCK_CLEAR_MASK & GML_SPDIF_RATE_CLEAR_MASK;
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 DE_ACT(("set_sample_rate: %d invalid!\n", rate));
218 return -EINVAL;
219 }
220
221 control_reg |= clock;
222
223 chip->comm_page->sample_rate = cpu_to_le32(rate); /* ignored by the DSP */
224 chip->sample_rate = rate;
225 DE_ACT(("set_sample_rate: %d clock %d\n", rate, clock));
226
227 return write_control_reg(chip, control_reg, FALSE);
228}
229
230
231
232static int set_input_clock(struct echoaudio *chip, u16 clock)
233{
234 u32 control_reg, clocks_from_dsp;
235
236 DE_ACT(("set_input_clock:\n"));
237
238 /* Mask off the clock select bits */
239 control_reg = le32_to_cpu(chip->comm_page->control_register) &
240 GML_CLOCK_CLEAR_MASK;
241 clocks_from_dsp = le32_to_cpu(chip->comm_page->status_clocks);
242
243 switch (clock) {
244 case ECHO_CLOCK_INTERNAL:
245 DE_ACT(("Set Gina24 clock to INTERNAL\n"));
246 chip->input_clock = ECHO_CLOCK_INTERNAL;
247 return set_sample_rate(chip, chip->sample_rate);
248 case ECHO_CLOCK_SPDIF:
249 if (chip->digital_mode == DIGITAL_MODE_ADAT)
250 return -EAGAIN;
251 DE_ACT(("Set Gina24 clock to SPDIF\n"));
252 control_reg |= GML_SPDIF_CLOCK;
253 if (clocks_from_dsp & GML_CLOCK_DETECT_BIT_SPDIF96)
254 control_reg |= GML_DOUBLE_SPEED_MODE;
255 else
256 control_reg &= ~GML_DOUBLE_SPEED_MODE;
257 break;
258 case ECHO_CLOCK_ADAT:
259 if (chip->digital_mode != DIGITAL_MODE_ADAT)
260 return -EAGAIN;
261 DE_ACT(("Set Gina24 clock to ADAT\n"));
262 control_reg |= GML_ADAT_CLOCK;
263 control_reg &= ~GML_DOUBLE_SPEED_MODE;
264 break;
265 case ECHO_CLOCK_ESYNC:
266 DE_ACT(("Set Gina24 clock to ESYNC\n"));
267 control_reg |= GML_ESYNC_CLOCK;
268 control_reg &= ~GML_DOUBLE_SPEED_MODE;
269 break;
270 case ECHO_CLOCK_ESYNC96:
271 DE_ACT(("Set Gina24 clock to ESYNC96\n"));
272 control_reg |= GML_ESYNC_CLOCK | GML_DOUBLE_SPEED_MODE;
273 break;
274 default:
275 DE_ACT(("Input clock 0x%x not supported for Gina24\n", clock));
276 return -EINVAL;
277 }
278
279 chip->input_clock = clock;
280 return write_control_reg(chip, control_reg, TRUE);
281}
282
283
284
285static int dsp_set_digital_mode(struct echoaudio *chip, u8 mode)
286{
287 u32 control_reg;
288 int err, incompatible_clock;
289
290 /* Set clock to "internal" if it's not compatible with the new mode */
291 incompatible_clock = FALSE;
292 switch (mode) {
293 case DIGITAL_MODE_SPDIF_OPTICAL:
294 case DIGITAL_MODE_SPDIF_CDROM:
295 case DIGITAL_MODE_SPDIF_RCA:
296 if (chip->input_clock == ECHO_CLOCK_ADAT)
297 incompatible_clock = TRUE;
298 break;
299 case DIGITAL_MODE_ADAT:
300 if (chip->input_clock == ECHO_CLOCK_SPDIF)
301 incompatible_clock = TRUE;
302 break;
303 default:
304 DE_ACT(("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 DE_ACT(("set_digital_mode to %d\n", chip->digital_mode));
345 return incompatible_clock;
346}