blob: 8eff2b4f5ceb288a390fc6a548edd10d037c899a [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
Takashi Iwaida3cec32008-08-08 17:12:14 +020044 if (snd_BUG_ON((subdevice_id & 0xfff0) != GINA24))
45 return -ENODEV;
Giuliano Pochinidd7b2542006-06-28 13:53:41 +020046
47 if ((err = init_dsp_comm_page(chip))) {
Sudip Mukherjeeb5b4a412014-11-03 16:04:13 +053048 dev_err(chip->card->dev,
49 "init_hw - could not initialize DSP comm page\n");
Giuliano Pochinidd7b2542006-06-28 13:53:41 +020050 return err;
51 }
52
53 chip->device_id = device_id;
54 chip->subdevice_id = subdevice_id;
Mark Brown3f6175e2015-08-10 13:02:53 +010055 chip->bad_board = true;
Giuliano Pochinidd7b2542006-06-28 13:53:41 +020056 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;
Giuliano Pochinidd7b2542006-06-28 13:53:41 +020060
61 /* Gina24 comes in both '301 and '361 flavors */
62 if (chip->device_id == DEVICE_ID_56361) {
Giuliano Pochini19b50062010-02-14 18:15:34 +010063 chip->dsp_code_to_load = FW_GINA24_361_DSP;
Giuliano Pochinidd7b2542006-06-28 13:53:41 +020064 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 {
Giuliano Pochini19b50062010-02-14 18:15:34 +010069 chip->dsp_code_to_load = FW_GINA24_301_DSP;
Giuliano Pochinidd7b2542006-06-28 13:53:41 +020070 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;
Mark Brown3f6175e2015-08-10 13:02:53 +010079 chip->bad_board = false;
Giuliano Pochinidd7b2542006-06-28 13:53:41 +020080
Giuliano Pochinidd7b2542006-06-28 13:53:41 +020081 return err;
82}
83
84
85
Giuliano Pochiniad3499f2010-02-14 18:15:59 +010086static int set_mixer_defaults(struct echoaudio *chip)
87{
88 chip->digital_mode = DIGITAL_MODE_SPDIF_RCA;
Mark Brown3f6175e2015-08-10 13:02:53 +010089 chip->professional_spdif = false;
90 chip->digital_in_automute = true;
Giuliano Pochiniad3499f2010-02-14 18:15:59 +010091 return init_line_levels(chip);
92}
93
94
95
Giuliano Pochinidd7b2542006-06-28 13:53:41 +020096static 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;
Giuliano Pochini19b50062010-02-14 18:15:34 +0100126 short asic;
Giuliano Pochinidd7b2542006-06-28 13:53:41 +0200127
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)
Giuliano Pochini19b50062010-02-14 18:15:34 +0100136 asic = FW_GINA24_361_ASIC;
Giuliano Pochinidd7b2542006-06-28 13:53:41 +0200137 else
Giuliano Pochini19b50062010-02-14 18:15:34 +0100138 asic = FW_GINA24_301_ASIC;
Giuliano Pochinidd7b2542006-06-28 13:53:41 +0200139
Giuliano Pochini19b50062010-02-14 18:15:34 +0100140 err = load_asic_generic(chip, DSP_FNC_LOAD_GINA24_ASIC, asic);
141 if (err < 0)
Giuliano Pochinidd7b2542006-06-28 13:53:41 +0200142 return err;
143
Giuliano Pochini19b50062010-02-14 18:15:34 +0100144 chip->asic_code = asic;
Giuliano Pochinidd7b2542006-06-28 13:53:41 +0200145
146 /* Now give the new ASIC a little time to set up */
147 mdelay(10);
148 /* See if it worked */
149 err = check_asic_status(chip);
150
151 /* Set up the control register if the load succeeded -
152 48 kHz, internal clock, S/PDIF RCA mode */
153 if (!err) {
154 control_reg = GML_CONVERTER_ENABLE | GML_48KHZ;
Mark Brown3f6175e2015-08-10 13:02:53 +0100155 err = write_control_reg(chip, control_reg, true);
Giuliano Pochinidd7b2542006-06-28 13:53:41 +0200156 }
Giuliano Pochinidd7b2542006-06-28 13:53:41 +0200157 return err;
158}
159
160
161
162static int set_sample_rate(struct echoaudio *chip, u32 rate)
163{
164 u32 control_reg, clock;
165
Takashi Iwaida3cec32008-08-08 17:12:14 +0200166 if (snd_BUG_ON(rate >= 50000 &&
167 chip->digital_mode == DIGITAL_MODE_ADAT))
168 return -EINVAL;
Giuliano Pochinidd7b2542006-06-28 13:53:41 +0200169
170 /* Only set the clock for internal mode. */
171 if (chip->input_clock != ECHO_CLOCK_INTERNAL) {
Sudip Mukherjeeb5b4a412014-11-03 16:04:13 +0530172 dev_warn(chip->card->dev,
173 "Cannot set sample rate - clock not set to CLK_CLOCKININTERNAL\n");
Giuliano Pochinidd7b2542006-06-28 13:53:41 +0200174 /* Save the rate anyhow */
175 chip->comm_page->sample_rate = cpu_to_le32(rate);
176 chip->sample_rate = rate;
177 return 0;
178 }
179
180 clock = 0;
181
182 control_reg = le32_to_cpu(chip->comm_page->control_register);
183 control_reg &= GML_CLOCK_CLEAR_MASK & GML_SPDIF_RATE_CLEAR_MASK;
184
185 switch (rate) {
186 case 96000:
187 clock = GML_96KHZ;
188 break;
189 case 88200:
190 clock = GML_88KHZ;
191 break;
192 case 48000:
193 clock = GML_48KHZ | GML_SPDIF_SAMPLE_RATE1;
194 break;
195 case 44100:
196 clock = GML_44KHZ;
197 /* Professional mode ? */
198 if (control_reg & GML_SPDIF_PRO_MODE)
199 clock |= GML_SPDIF_SAMPLE_RATE0;
200 break;
201 case 32000:
202 clock = GML_32KHZ | GML_SPDIF_SAMPLE_RATE0 |
203 GML_SPDIF_SAMPLE_RATE1;
204 break;
205 case 22050:
206 clock = GML_22KHZ;
207 break;
208 case 16000:
209 clock = GML_16KHZ;
210 break;
211 case 11025:
212 clock = GML_11KHZ;
213 break;
214 case 8000:
215 clock = GML_8KHZ;
216 break;
217 default:
Sudip Mukherjeeb5b4a412014-11-03 16:04:13 +0530218 dev_err(chip->card->dev,
219 "set_sample_rate: %d invalid!\n", rate);
Giuliano Pochinidd7b2542006-06-28 13:53:41 +0200220 return -EINVAL;
221 }
222
223 control_reg |= clock;
224
225 chip->comm_page->sample_rate = cpu_to_le32(rate); /* ignored by the DSP */
226 chip->sample_rate = rate;
Sudip Mukherjeeb5b4a412014-11-03 16:04:13 +0530227 dev_dbg(chip->card->dev, "set_sample_rate: %d clock %d\n", rate, clock);
Giuliano Pochinidd7b2542006-06-28 13:53:41 +0200228
Mark Brown3f6175e2015-08-10 13:02:53 +0100229 return write_control_reg(chip, control_reg, false);
Giuliano Pochinidd7b2542006-06-28 13:53:41 +0200230}
231
232
233
234static int set_input_clock(struct echoaudio *chip, u16 clock)
235{
236 u32 control_reg, clocks_from_dsp;
237
Giuliano Pochinidd7b2542006-06-28 13:53:41 +0200238
239 /* Mask off the clock select bits */
240 control_reg = le32_to_cpu(chip->comm_page->control_register) &
241 GML_CLOCK_CLEAR_MASK;
242 clocks_from_dsp = le32_to_cpu(chip->comm_page->status_clocks);
243
244 switch (clock) {
245 case ECHO_CLOCK_INTERNAL:
Giuliano Pochinidd7b2542006-06-28 13:53:41 +0200246 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;
Giuliano Pochinidd7b2542006-06-28 13:53:41 +0200251 control_reg |= GML_SPDIF_CLOCK;
252 if (clocks_from_dsp & GML_CLOCK_DETECT_BIT_SPDIF96)
253 control_reg |= GML_DOUBLE_SPEED_MODE;
254 else
255 control_reg &= ~GML_DOUBLE_SPEED_MODE;
256 break;
257 case ECHO_CLOCK_ADAT:
258 if (chip->digital_mode != DIGITAL_MODE_ADAT)
259 return -EAGAIN;
Giuliano Pochinidd7b2542006-06-28 13:53:41 +0200260 control_reg |= GML_ADAT_CLOCK;
261 control_reg &= ~GML_DOUBLE_SPEED_MODE;
262 break;
263 case ECHO_CLOCK_ESYNC:
Giuliano Pochinidd7b2542006-06-28 13:53:41 +0200264 control_reg |= GML_ESYNC_CLOCK;
265 control_reg &= ~GML_DOUBLE_SPEED_MODE;
266 break;
267 case ECHO_CLOCK_ESYNC96:
Giuliano Pochinidd7b2542006-06-28 13:53:41 +0200268 control_reg |= GML_ESYNC_CLOCK | GML_DOUBLE_SPEED_MODE;
269 break;
270 default:
Sudip Mukherjeeb5b4a412014-11-03 16:04:13 +0530271 dev_err(chip->card->dev,
272 "Input clock 0x%x not supported for Gina24\n", clock);
Giuliano Pochinidd7b2542006-06-28 13:53:41 +0200273 return -EINVAL;
274 }
275
276 chip->input_clock = clock;
Mark Brown3f6175e2015-08-10 13:02:53 +0100277 return write_control_reg(chip, control_reg, true);
Giuliano Pochinidd7b2542006-06-28 13:53:41 +0200278}
279
280
281
282static int dsp_set_digital_mode(struct echoaudio *chip, u8 mode)
283{
284 u32 control_reg;
285 int err, incompatible_clock;
286
287 /* Set clock to "internal" if it's not compatible with the new mode */
Mark Brown3f6175e2015-08-10 13:02:53 +0100288 incompatible_clock = false;
Giuliano Pochinidd7b2542006-06-28 13:53:41 +0200289 switch (mode) {
290 case DIGITAL_MODE_SPDIF_OPTICAL:
291 case DIGITAL_MODE_SPDIF_CDROM:
292 case DIGITAL_MODE_SPDIF_RCA:
293 if (chip->input_clock == ECHO_CLOCK_ADAT)
Mark Brown3f6175e2015-08-10 13:02:53 +0100294 incompatible_clock = true;
Giuliano Pochinidd7b2542006-06-28 13:53:41 +0200295 break;
296 case DIGITAL_MODE_ADAT:
297 if (chip->input_clock == ECHO_CLOCK_SPDIF)
Mark Brown3f6175e2015-08-10 13:02:53 +0100298 incompatible_clock = true;
Giuliano Pochinidd7b2542006-06-28 13:53:41 +0200299 break;
300 default:
Sudip Mukherjeeb5b4a412014-11-03 16:04:13 +0530301 dev_err(chip->card->dev,
302 "Digital mode not supported: %d\n", mode);
Giuliano Pochinidd7b2542006-06-28 13:53:41 +0200303 return -EINVAL;
304 }
305
306 spin_lock_irq(&chip->lock);
307
308 if (incompatible_clock) { /* Switch to 48KHz, internal */
309 chip->sample_rate = 48000;
310 set_input_clock(chip, ECHO_CLOCK_INTERNAL);
311 }
312
313 /* Clear the current digital mode */
314 control_reg = le32_to_cpu(chip->comm_page->control_register);
315 control_reg &= GML_DIGITAL_MODE_CLEAR_MASK;
316
317 /* Tweak the control reg */
318 switch (mode) {
319 case DIGITAL_MODE_SPDIF_OPTICAL:
320 control_reg |= GML_SPDIF_OPTICAL_MODE;
321 break;
322 case DIGITAL_MODE_SPDIF_CDROM:
323 /* '361 Gina24 cards do not have the S/PDIF CD-ROM mode */
324 if (chip->device_id == DEVICE_ID_56301)
325 control_reg |= GML_SPDIF_CDROM_MODE;
326 break;
327 case DIGITAL_MODE_SPDIF_RCA:
328 /* GML_SPDIF_OPTICAL_MODE bit cleared */
329 break;
330 case DIGITAL_MODE_ADAT:
331 control_reg |= GML_ADAT_MODE;
332 control_reg &= ~GML_DOUBLE_SPEED_MODE;
333 break;
334 }
335
Mark Brown3f6175e2015-08-10 13:02:53 +0100336 err = write_control_reg(chip, control_reg, true);
Giuliano Pochinidd7b2542006-06-28 13:53:41 +0200337 spin_unlock_irq(&chip->lock);
338 if (err < 0)
339 return err;
340 chip->digital_mode = mode;
341
Sudip Mukherjeeb5b4a412014-11-03 16:04:13 +0530342 dev_dbg(chip->card->dev,
343 "set_digital_mode to %d\n", chip->digital_mode);
Giuliano Pochinidd7b2542006-06-28 13:53:41 +0200344 return incompatible_clock;
345}