blob: c8ea57612d22863c56a35fbfb13f84a44b3d9e9e [file] [log] [blame]
Giuliano Pochinidd7b2542006-06-28 13:53:41 +02001/****************************************************************************
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);
Giuliano Pochini19b50062010-02-14 18:15:34 +010036static int load_asic_generic(struct echoaudio *chip, u32 cmd, short asic);
Giuliano Pochinidd7b2542006-06-28 13:53:41 +020037static int check_asic_status(struct echoaudio *chip);
38
39
40static int init_hw(struct echoaudio *chip, u16 device_id, u16 subdevice_id)
41{
42 int err;
43
Sudip Mukherjeeb5b4a412014-11-03 16:04:13 +053044 dev_dbg(chip->card->dev, "init_hw() - Gina24\n");
Takashi Iwaida3cec32008-08-08 17:12:14 +020045 if (snd_BUG_ON((subdevice_id & 0xfff0) != GINA24))
46 return -ENODEV;
Giuliano Pochinidd7b2542006-06-28 13:53:41 +020047
48 if ((err = init_dsp_comm_page(chip))) {
Sudip Mukherjeeb5b4a412014-11-03 16:04:13 +053049 dev_err(chip->card->dev,
50 "init_hw - could not initialize DSP comm page\n");
Giuliano Pochinidd7b2542006-06-28 13:53:41 +020051 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;
Giuliano Pochinidd7b2542006-06-28 13:53:41 +020061
62 /* Gina24 comes in both '301 and '361 flavors */
63 if (chip->device_id == DEVICE_ID_56361) {
Giuliano Pochini19b50062010-02-14 18:15:34 +010064 chip->dsp_code_to_load = FW_GINA24_361_DSP;
Giuliano Pochinidd7b2542006-06-28 13:53:41 +020065 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 {
Giuliano Pochini19b50062010-02-14 18:15:34 +010070 chip->dsp_code_to_load = FW_GINA24_301_DSP;
Giuliano Pochinidd7b2542006-06-28 13:53:41 +020071 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 if ((err = load_firmware(chip)) < 0)
79 return err;
80 chip->bad_board = FALSE;
81
Sudip Mukherjeeb5b4a412014-11-03 16:04:13 +053082 dev_dbg(chip->card->dev, "init_hw done\n");
Giuliano Pochinidd7b2542006-06-28 13:53:41 +020083 return err;
84}
85
86
87
Giuliano Pochiniad3499f2010-02-14 18:15:59 +010088static 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
Giuliano Pochinidd7b2542006-06-28 13:53:41 +020098static 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
123interesting to happen. */
124static int load_asic(struct echoaudio *chip)
125{
126 u32 control_reg;
127 int err;
Giuliano Pochini19b50062010-02-14 18:15:34 +0100128 short asic;
Giuliano Pochinidd7b2542006-06-28 13:53:41 +0200129
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)
Giuliano Pochini19b50062010-02-14 18:15:34 +0100138 asic = FW_GINA24_361_ASIC;
Giuliano Pochinidd7b2542006-06-28 13:53:41 +0200139 else
Giuliano Pochini19b50062010-02-14 18:15:34 +0100140 asic = FW_GINA24_301_ASIC;
Giuliano Pochinidd7b2542006-06-28 13:53:41 +0200141
Giuliano Pochini19b50062010-02-14 18:15:34 +0100142 err = load_asic_generic(chip, DSP_FNC_LOAD_GINA24_ASIC, asic);
143 if (err < 0)
Giuliano Pochinidd7b2542006-06-28 13:53:41 +0200144 return err;
145
Giuliano Pochini19b50062010-02-14 18:15:34 +0100146 chip->asic_code = asic;
Giuliano Pochinidd7b2542006-06-28 13:53:41 +0200147
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 }
Sudip Mukherjeeb5b4a412014-11-03 16:04:13 +0530159 dev_dbg(chip->card->dev, "load_asic() done\n");
Giuliano Pochinidd7b2542006-06-28 13:53:41 +0200160 return err;
161}
162
163
164
165static int set_sample_rate(struct echoaudio *chip, u32 rate)
166{
167 u32 control_reg, clock;
168
Takashi Iwaida3cec32008-08-08 17:12:14 +0200169 if (snd_BUG_ON(rate >= 50000 &&
170 chip->digital_mode == DIGITAL_MODE_ADAT))
171 return -EINVAL;
Giuliano Pochinidd7b2542006-06-28 13:53:41 +0200172
173 /* Only set the clock for internal mode. */
174 if (chip->input_clock != ECHO_CLOCK_INTERNAL) {
Sudip Mukherjeeb5b4a412014-11-03 16:04:13 +0530175 dev_warn(chip->card->dev,
176 "Cannot set sample rate - clock not set to CLK_CLOCKININTERNAL\n");
Giuliano Pochinidd7b2542006-06-28 13:53:41 +0200177 /* Save the rate anyhow */
178 chip->comm_page->sample_rate = cpu_to_le32(rate);
179 chip->sample_rate = rate;
180 return 0;
181 }
182
183 clock = 0;
184
185 control_reg = le32_to_cpu(chip->comm_page->control_register);
186 control_reg &= GML_CLOCK_CLEAR_MASK & GML_SPDIF_RATE_CLEAR_MASK;
187
188 switch (rate) {
189 case 96000:
190 clock = GML_96KHZ;
191 break;
192 case 88200:
193 clock = GML_88KHZ;
194 break;
195 case 48000:
196 clock = GML_48KHZ | GML_SPDIF_SAMPLE_RATE1;
197 break;
198 case 44100:
199 clock = GML_44KHZ;
200 /* Professional mode ? */
201 if (control_reg & GML_SPDIF_PRO_MODE)
202 clock |= GML_SPDIF_SAMPLE_RATE0;
203 break;
204 case 32000:
205 clock = GML_32KHZ | GML_SPDIF_SAMPLE_RATE0 |
206 GML_SPDIF_SAMPLE_RATE1;
207 break;
208 case 22050:
209 clock = GML_22KHZ;
210 break;
211 case 16000:
212 clock = GML_16KHZ;
213 break;
214 case 11025:
215 clock = GML_11KHZ;
216 break;
217 case 8000:
218 clock = GML_8KHZ;
219 break;
220 default:
Sudip Mukherjeeb5b4a412014-11-03 16:04:13 +0530221 dev_err(chip->card->dev,
222 "set_sample_rate: %d invalid!\n", rate);
Giuliano Pochinidd7b2542006-06-28 13:53:41 +0200223 return -EINVAL;
224 }
225
226 control_reg |= clock;
227
228 chip->comm_page->sample_rate = cpu_to_le32(rate); /* ignored by the DSP */
229 chip->sample_rate = rate;
Sudip Mukherjeeb5b4a412014-11-03 16:04:13 +0530230 dev_dbg(chip->card->dev, "set_sample_rate: %d clock %d\n", rate, clock);
Giuliano Pochinidd7b2542006-06-28 13:53:41 +0200231
232 return write_control_reg(chip, control_reg, FALSE);
233}
234
235
236
237static int set_input_clock(struct echoaudio *chip, u16 clock)
238{
239 u32 control_reg, clocks_from_dsp;
240
Sudip Mukherjeeb5b4a412014-11-03 16:04:13 +0530241 dev_dbg(chip->card->dev, "set_input_clock:\n");
Giuliano Pochinidd7b2542006-06-28 13:53:41 +0200242
243 /* Mask off the clock select bits */
244 control_reg = le32_to_cpu(chip->comm_page->control_register) &
245 GML_CLOCK_CLEAR_MASK;
246 clocks_from_dsp = le32_to_cpu(chip->comm_page->status_clocks);
247
248 switch (clock) {
249 case ECHO_CLOCK_INTERNAL:
Sudip Mukherjeeb5b4a412014-11-03 16:04:13 +0530250 dev_dbg(chip->card->dev, "Set Gina24 clock to INTERNAL\n");
Giuliano Pochinidd7b2542006-06-28 13:53:41 +0200251 chip->input_clock = ECHO_CLOCK_INTERNAL;
252 return set_sample_rate(chip, chip->sample_rate);
253 case ECHO_CLOCK_SPDIF:
254 if (chip->digital_mode == DIGITAL_MODE_ADAT)
255 return -EAGAIN;
Sudip Mukherjeeb5b4a412014-11-03 16:04:13 +0530256 dev_dbg(chip->card->dev, "Set Gina24 clock to SPDIF\n");
Giuliano Pochinidd7b2542006-06-28 13:53:41 +0200257 control_reg |= GML_SPDIF_CLOCK;
258 if (clocks_from_dsp & GML_CLOCK_DETECT_BIT_SPDIF96)
259 control_reg |= GML_DOUBLE_SPEED_MODE;
260 else
261 control_reg &= ~GML_DOUBLE_SPEED_MODE;
262 break;
263 case ECHO_CLOCK_ADAT:
264 if (chip->digital_mode != DIGITAL_MODE_ADAT)
265 return -EAGAIN;
Sudip Mukherjeeb5b4a412014-11-03 16:04:13 +0530266 dev_dbg(chip->card->dev, "Set Gina24 clock to ADAT\n");
Giuliano Pochinidd7b2542006-06-28 13:53:41 +0200267 control_reg |= GML_ADAT_CLOCK;
268 control_reg &= ~GML_DOUBLE_SPEED_MODE;
269 break;
270 case ECHO_CLOCK_ESYNC:
Sudip Mukherjeeb5b4a412014-11-03 16:04:13 +0530271 dev_dbg(chip->card->dev, "Set Gina24 clock to ESYNC\n");
Giuliano Pochinidd7b2542006-06-28 13:53:41 +0200272 control_reg |= GML_ESYNC_CLOCK;
273 control_reg &= ~GML_DOUBLE_SPEED_MODE;
274 break;
275 case ECHO_CLOCK_ESYNC96:
Sudip Mukherjeeb5b4a412014-11-03 16:04:13 +0530276 dev_dbg(chip->card->dev, "Set Gina24 clock to ESYNC96\n");
Giuliano Pochinidd7b2542006-06-28 13:53:41 +0200277 control_reg |= GML_ESYNC_CLOCK | GML_DOUBLE_SPEED_MODE;
278 break;
279 default:
Sudip Mukherjeeb5b4a412014-11-03 16:04:13 +0530280 dev_err(chip->card->dev,
281 "Input clock 0x%x not supported for Gina24\n", clock);
Giuliano Pochinidd7b2542006-06-28 13:53:41 +0200282 return -EINVAL;
283 }
284
285 chip->input_clock = clock;
286 return write_control_reg(chip, control_reg, TRUE);
287}
288
289
290
291static int dsp_set_digital_mode(struct echoaudio *chip, u8 mode)
292{
293 u32 control_reg;
294 int err, incompatible_clock;
295
296 /* Set clock to "internal" if it's not compatible with the new mode */
297 incompatible_clock = FALSE;
298 switch (mode) {
299 case DIGITAL_MODE_SPDIF_OPTICAL:
300 case DIGITAL_MODE_SPDIF_CDROM:
301 case DIGITAL_MODE_SPDIF_RCA:
302 if (chip->input_clock == ECHO_CLOCK_ADAT)
303 incompatible_clock = TRUE;
304 break;
305 case DIGITAL_MODE_ADAT:
306 if (chip->input_clock == ECHO_CLOCK_SPDIF)
307 incompatible_clock = TRUE;
308 break;
309 default:
Sudip Mukherjeeb5b4a412014-11-03 16:04:13 +0530310 dev_err(chip->card->dev,
311 "Digital mode not supported: %d\n", mode);
Giuliano Pochinidd7b2542006-06-28 13:53:41 +0200312 return -EINVAL;
313 }
314
315 spin_lock_irq(&chip->lock);
316
317 if (incompatible_clock) { /* Switch to 48KHz, internal */
318 chip->sample_rate = 48000;
319 set_input_clock(chip, ECHO_CLOCK_INTERNAL);
320 }
321
322 /* Clear the current digital mode */
323 control_reg = le32_to_cpu(chip->comm_page->control_register);
324 control_reg &= GML_DIGITAL_MODE_CLEAR_MASK;
325
326 /* Tweak the control reg */
327 switch (mode) {
328 case DIGITAL_MODE_SPDIF_OPTICAL:
329 control_reg |= GML_SPDIF_OPTICAL_MODE;
330 break;
331 case DIGITAL_MODE_SPDIF_CDROM:
332 /* '361 Gina24 cards do not have the S/PDIF CD-ROM mode */
333 if (chip->device_id == DEVICE_ID_56301)
334 control_reg |= GML_SPDIF_CDROM_MODE;
335 break;
336 case DIGITAL_MODE_SPDIF_RCA:
337 /* GML_SPDIF_OPTICAL_MODE bit cleared */
338 break;
339 case DIGITAL_MODE_ADAT:
340 control_reg |= GML_ADAT_MODE;
341 control_reg &= ~GML_DOUBLE_SPEED_MODE;
342 break;
343 }
344
345 err = write_control_reg(chip, control_reg, TRUE);
346 spin_unlock_irq(&chip->lock);
347 if (err < 0)
348 return err;
349 chip->digital_mode = mode;
350
Sudip Mukherjeeb5b4a412014-11-03 16:04:13 +0530351 dev_dbg(chip->card->dev,
352 "set_digital_mode to %d\n", chip->digital_mode);
Giuliano Pochinidd7b2542006-06-28 13:53:41 +0200353 return incompatible_clock;
354}