Committer: Michael Beasley <mike@snafu.setup>
[mikesnafu-overlay.git] / sound / pci / echoaudio / layla20_dsp.c
blob990c9a60a0a89a81f8acf6c280faa50395d17012
1 /****************************************************************************
3 Copyright Echo Digital Audio Corporation (c) 1998 - 2004
4 All rights reserved
5 www.echoaudio.com
7 This file is part of Echo Digital Audio's generic driver library.
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.
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.
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.
24 *************************************************************************
26 Translation from C++ and adaptation for use in ALSA-Driver
27 were made by Giuliano Pochini <pochini@shiny.it>
29 ****************************************************************************/
32 static int read_dsp(struct echoaudio *chip, u32 *data);
33 static int set_professional_spdif(struct echoaudio *chip, char prof);
34 static int load_asic_generic(struct echoaudio *chip, u32 cmd,
35 const struct firmware *asic);
36 static int check_asic_status(struct echoaudio *chip);
37 static int update_flags(struct echoaudio *chip);
40 static int init_hw(struct echoaudio *chip, u16 device_id, u16 subdevice_id)
42 int err;
44 DE_INIT(("init_hw() - Layla20\n"));
45 snd_assert((subdevice_id & 0xfff0) == LAYLA20, return -ENODEV);
47 if ((err = init_dsp_comm_page(chip))) {
48 DE_INIT(("init_hw - could not initialize DSP comm page\n"));
49 return err;
52 chip->device_id = device_id;
53 chip->subdevice_id = subdevice_id;
54 chip->bad_board = TRUE;
55 chip->has_midi = TRUE;
56 chip->dsp_code_to_load = &card_fw[FW_LAYLA20_DSP];
57 chip->input_clock_types =
58 ECHO_CLOCK_BIT_INTERNAL | ECHO_CLOCK_BIT_SPDIF |
59 ECHO_CLOCK_BIT_WORD | ECHO_CLOCK_BIT_SUPER;
60 chip->output_clock_types =
61 ECHO_CLOCK_BIT_WORD | ECHO_CLOCK_BIT_SUPER;
63 if ((err = load_firmware(chip)) < 0)
64 return err;
65 chip->bad_board = FALSE;
67 if ((err = init_line_levels(chip)) < 0)
68 return err;
70 err = set_professional_spdif(chip, TRUE);
72 DE_INIT(("init_hw done\n"));
73 return err;
78 static u32 detect_input_clocks(const struct echoaudio *chip)
80 u32 clocks_from_dsp, clock_bits;
82 /* Map the DSP clock detect bits to the generic driver clock detect bits */
83 clocks_from_dsp = le32_to_cpu(chip->comm_page->status_clocks);
85 clock_bits = ECHO_CLOCK_BIT_INTERNAL;
87 if (clocks_from_dsp & GLDM_CLOCK_DETECT_BIT_SPDIF)
88 clock_bits |= ECHO_CLOCK_BIT_SPDIF;
90 if (clocks_from_dsp & GLDM_CLOCK_DETECT_BIT_WORD) {
91 if (clocks_from_dsp & GLDM_CLOCK_DETECT_BIT_SUPER)
92 clock_bits |= ECHO_CLOCK_BIT_SUPER;
93 else
94 clock_bits |= ECHO_CLOCK_BIT_WORD;
97 return clock_bits;
102 /* ASIC status check - some cards have one or two ASICs that need to be
103 loaded. Once that load is complete, this function is called to see if
104 the load was successful.
105 If this load fails, it does not necessarily mean that the hardware is
106 defective - the external box may be disconnected or turned off.
107 This routine sometimes fails for Layla20; for Layla20, the loop runs
108 5 times and succeeds if it wins on three of the loops. */
109 static int check_asic_status(struct echoaudio *chip)
111 u32 asic_status;
112 int goodcnt, i;
114 chip->asic_loaded = FALSE;
115 for (i = goodcnt = 0; i < 5; i++) {
116 send_vector(chip, DSP_VC_TEST_ASIC);
118 /* The DSP will return a value to indicate whether or not
119 the ASIC is currently loaded */
120 if (read_dsp(chip, &asic_status) < 0) {
121 DE_ACT(("check_asic_status: failed on read_dsp\n"));
122 return -EIO;
125 if (asic_status == ASIC_ALREADY_LOADED) {
126 if (++goodcnt == 3) {
127 chip->asic_loaded = TRUE;
128 return 0;
132 return -EIO;
137 /* Layla20 has an ASIC in the external box */
138 static int load_asic(struct echoaudio *chip)
140 int err;
142 if (chip->asic_loaded)
143 return 0;
145 err = load_asic_generic(chip, DSP_FNC_LOAD_LAYLA_ASIC,
146 &card_fw[FW_LAYLA20_ASIC]);
147 if (err < 0)
148 return err;
150 /* Check if ASIC is alive and well. */
151 return check_asic_status(chip);
156 static int set_sample_rate(struct echoaudio *chip, u32 rate)
158 snd_assert(rate >= 8000 && rate <= 50000, return -EINVAL);
160 /* Only set the clock for internal mode. Do not return failure,
161 simply treat it as a non-event. */
162 if (chip->input_clock != ECHO_CLOCK_INTERNAL) {
163 DE_ACT(("set_sample_rate: Cannot set sample rate - "
164 "clock not set to CLK_CLOCKININTERNAL\n"));
165 chip->comm_page->sample_rate = cpu_to_le32(rate);
166 chip->sample_rate = rate;
167 return 0;
170 if (wait_handshake(chip))
171 return -EIO;
173 DE_ACT(("set_sample_rate(%d)\n", rate));
174 chip->sample_rate = rate;
175 chip->comm_page->sample_rate = cpu_to_le32(rate);
176 clear_handshake(chip);
177 return send_vector(chip, DSP_VC_SET_LAYLA_SAMPLE_RATE);
182 static int set_input_clock(struct echoaudio *chip, u16 clock_source)
184 u16 clock;
185 u32 rate;
187 DE_ACT(("set_input_clock:\n"));
188 rate = 0;
189 switch (clock_source) {
190 case ECHO_CLOCK_INTERNAL:
191 DE_ACT(("Set Layla20 clock to INTERNAL\n"));
192 rate = chip->sample_rate;
193 clock = LAYLA20_CLOCK_INTERNAL;
194 break;
195 case ECHO_CLOCK_SPDIF:
196 DE_ACT(("Set Layla20 clock to SPDIF\n"));
197 clock = LAYLA20_CLOCK_SPDIF;
198 break;
199 case ECHO_CLOCK_WORD:
200 DE_ACT(("Set Layla20 clock to WORD\n"));
201 clock = LAYLA20_CLOCK_WORD;
202 break;
203 case ECHO_CLOCK_SUPER:
204 DE_ACT(("Set Layla20 clock to SUPER\n"));
205 clock = LAYLA20_CLOCK_SUPER;
206 break;
207 default:
208 DE_ACT(("Input clock 0x%x not supported for Layla24\n",
209 clock_source));
210 return -EINVAL;
212 chip->input_clock = clock_source;
214 chip->comm_page->input_clock = cpu_to_le16(clock);
215 clear_handshake(chip);
216 send_vector(chip, DSP_VC_UPDATE_CLOCKS);
218 if (rate)
219 set_sample_rate(chip, rate);
221 return 0;
226 static int set_output_clock(struct echoaudio *chip, u16 clock)
228 DE_ACT(("set_output_clock: %d\n", clock));
229 switch (clock) {
230 case ECHO_CLOCK_SUPER:
231 clock = LAYLA20_OUTPUT_CLOCK_SUPER;
232 break;
233 case ECHO_CLOCK_WORD:
234 clock = LAYLA20_OUTPUT_CLOCK_WORD;
235 break;
236 default:
237 DE_ACT(("set_output_clock wrong clock\n"));
238 return -EINVAL;
241 if (wait_handshake(chip))
242 return -EIO;
244 chip->comm_page->output_clock = cpu_to_le16(clock);
245 chip->output_clock = clock;
246 clear_handshake(chip);
247 return send_vector(chip, DSP_VC_UPDATE_CLOCKS);
252 /* Set input bus gain (one unit is 0.5dB !) */
253 static int set_input_gain(struct echoaudio *chip, u16 input, int gain)
255 snd_assert(input < num_busses_in(chip), return -EINVAL);
257 if (wait_handshake(chip))
258 return -EIO;
260 chip->input_gain[input] = gain;
261 gain += GL20_INPUT_GAIN_MAGIC_NUMBER;
262 chip->comm_page->line_in_level[input] = gain;
263 return 0;
268 /* Tell the DSP to reread the flags from the comm page */
269 static int update_flags(struct echoaudio *chip)
271 if (wait_handshake(chip))
272 return -EIO;
273 clear_handshake(chip);
274 return send_vector(chip, DSP_VC_UPDATE_FLAGS);
279 static int set_professional_spdif(struct echoaudio *chip, char prof)
281 DE_ACT(("set_professional_spdif %d\n", prof));
282 if (prof)
283 chip->comm_page->flags |=
284 __constant_cpu_to_le32(DSP_FLAG_PROFESSIONAL_SPDIF);
285 else
286 chip->comm_page->flags &=
287 ~__constant_cpu_to_le32(DSP_FLAG_PROFESSIONAL_SPDIF);
288 chip->professional_spdif = prof;
289 return update_flags(chip);