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 
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);
38 
39 
40 static int init_hw(struct echoaudio *chip, u16 device_id, u16 subdevice_id)
41 {
42 	int err;
43 
44 	DE_INIT(("init_hw() - Layla20\n"));
45 	if (snd_BUG_ON((subdevice_id & 0xfff0) != LAYLA20))
46 		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->has_midi = TRUE;
57 	chip->dsp_code_to_load = &card_fw[FW_LAYLA20_DSP];
58 	chip->input_clock_types =
59 		ECHO_CLOCK_BIT_INTERNAL | ECHO_CLOCK_BIT_SPDIF |
60 		ECHO_CLOCK_BIT_WORD | ECHO_CLOCK_BIT_SUPER;
61 	chip->output_clock_types =
62 		ECHO_CLOCK_BIT_WORD | ECHO_CLOCK_BIT_SUPER;
63 
64 	if ((err = load_firmware(chip)) < 0)
65 		return err;
66 	chip->bad_board = FALSE;
67 
68 	if ((err = init_line_levels(chip)) < 0)
69 		return err;
70 
71 	err = set_professional_spdif(chip, TRUE);
72 
73 	DE_INIT(("init_hw done\n"));
74 	return err;
75 }
76 
77 
78 
79 static u32 detect_input_clocks(const struct echoaudio *chip)
80 {
81 	u32 clocks_from_dsp, clock_bits;
82 
83 	/* Map the DSP clock detect bits to the generic driver clock detect bits */
84 	clocks_from_dsp = le32_to_cpu(chip->comm_page->status_clocks);
85 
86 	clock_bits = ECHO_CLOCK_BIT_INTERNAL;
87 
88 	if (clocks_from_dsp & GLDM_CLOCK_DETECT_BIT_SPDIF)
89 		clock_bits |= ECHO_CLOCK_BIT_SPDIF;
90 
91 	if (clocks_from_dsp & GLDM_CLOCK_DETECT_BIT_WORD) {
92 		if (clocks_from_dsp & GLDM_CLOCK_DETECT_BIT_SUPER)
93 			clock_bits |= ECHO_CLOCK_BIT_SUPER;
94 		else
95 			clock_bits |= ECHO_CLOCK_BIT_WORD;
96 	}
97 
98 	return clock_bits;
99 }
100 
101 
102 
103 /* ASIC status check - some cards have one or two ASICs that need to be
104 loaded.  Once that load is complete, this function is called to see if
105 the load was successful.
106 If this load fails, it does not necessarily mean that the hardware is
107 defective - the external box may be disconnected or turned off.
108 This routine sometimes fails for Layla20; for Layla20, the loop runs
109 5 times and succeeds if it wins on three of the loops. */
110 static int check_asic_status(struct echoaudio *chip)
111 {
112 	u32 asic_status;
113 	int goodcnt, i;
114 
115 	chip->asic_loaded = FALSE;
116 	for (i = goodcnt = 0; i < 5; i++) {
117 		send_vector(chip, DSP_VC_TEST_ASIC);
118 
119 		/* The DSP will return a value to indicate whether or not
120 		   the ASIC is currently loaded */
121 		if (read_dsp(chip, &asic_status) < 0) {
122 			DE_ACT(("check_asic_status: failed on read_dsp\n"));
123 			return -EIO;
124 		}
125 
126 		if (asic_status == ASIC_ALREADY_LOADED) {
127 			if (++goodcnt == 3) {
128 				chip->asic_loaded = TRUE;
129 				return 0;
130 			}
131 		}
132 	}
133 	return -EIO;
134 }
135 
136 
137 
138 /* Layla20 has an ASIC in the external box */
139 static int load_asic(struct echoaudio *chip)
140 {
141 	int err;
142 
143 	if (chip->asic_loaded)
144 		return 0;
145 
146 	err = load_asic_generic(chip, DSP_FNC_LOAD_LAYLA_ASIC,
147 				&card_fw[FW_LAYLA20_ASIC]);
148 	if (err < 0)
149 		return err;
150 
151 	/* Check if ASIC is alive and well. */
152 	return check_asic_status(chip);
153 }
154 
155 
156 
157 static int set_sample_rate(struct echoaudio *chip, u32 rate)
158 {
159 	if (snd_BUG_ON(rate < 8000 || rate > 50000))
160 		return -EINVAL;
161 
162 	/* Only set the clock for internal mode. Do not return failure,
163 	   simply treat it as a non-event. */
164 	if (chip->input_clock != ECHO_CLOCK_INTERNAL) {
165 		DE_ACT(("set_sample_rate: Cannot set sample rate - "
166 			"clock not set to CLK_CLOCKININTERNAL\n"));
167 		chip->comm_page->sample_rate = cpu_to_le32(rate);
168 		chip->sample_rate = rate;
169 		return 0;
170 	}
171 
172 	if (wait_handshake(chip))
173 		return -EIO;
174 
175 	DE_ACT(("set_sample_rate(%d)\n", rate));
176 	chip->sample_rate = rate;
177 	chip->comm_page->sample_rate = cpu_to_le32(rate);
178 	clear_handshake(chip);
179 	return send_vector(chip, DSP_VC_SET_LAYLA_SAMPLE_RATE);
180 }
181 
182 
183 
184 static int set_input_clock(struct echoaudio *chip, u16 clock_source)
185 {
186 	u16 clock;
187 	u32 rate;
188 
189 	DE_ACT(("set_input_clock:\n"));
190 	rate = 0;
191 	switch (clock_source) {
192 	case ECHO_CLOCK_INTERNAL:
193 		DE_ACT(("Set Layla20 clock to INTERNAL\n"));
194 		rate = chip->sample_rate;
195 		clock = LAYLA20_CLOCK_INTERNAL;
196 		break;
197 	case ECHO_CLOCK_SPDIF:
198 		DE_ACT(("Set Layla20 clock to SPDIF\n"));
199 		clock = LAYLA20_CLOCK_SPDIF;
200 		break;
201 	case ECHO_CLOCK_WORD:
202 		DE_ACT(("Set Layla20 clock to WORD\n"));
203 		clock = LAYLA20_CLOCK_WORD;
204 		break;
205 	case ECHO_CLOCK_SUPER:
206 		DE_ACT(("Set Layla20 clock to SUPER\n"));
207 		clock = LAYLA20_CLOCK_SUPER;
208 		break;
209 	default:
210 		DE_ACT(("Input clock 0x%x not supported for Layla24\n",
211 			clock_source));
212 		return -EINVAL;
213 	}
214 	chip->input_clock = clock_source;
215 
216 	chip->comm_page->input_clock = cpu_to_le16(clock);
217 	clear_handshake(chip);
218 	send_vector(chip, DSP_VC_UPDATE_CLOCKS);
219 
220 	if (rate)
221 		set_sample_rate(chip, rate);
222 
223 	return 0;
224 }
225 
226 
227 
228 static int set_output_clock(struct echoaudio *chip, u16 clock)
229 {
230 	DE_ACT(("set_output_clock: %d\n", clock));
231 	switch (clock) {
232 	case ECHO_CLOCK_SUPER:
233 		clock = LAYLA20_OUTPUT_CLOCK_SUPER;
234 		break;
235 	case ECHO_CLOCK_WORD:
236 		clock = LAYLA20_OUTPUT_CLOCK_WORD;
237 		break;
238 	default:
239 		DE_ACT(("set_output_clock wrong clock\n"));
240 		return -EINVAL;
241 	}
242 
243 	if (wait_handshake(chip))
244 		return -EIO;
245 
246 	chip->comm_page->output_clock = cpu_to_le16(clock);
247 	chip->output_clock = clock;
248 	clear_handshake(chip);
249 	return send_vector(chip, DSP_VC_UPDATE_CLOCKS);
250 }
251 
252 
253 
254 /* Set input bus gain (one unit is 0.5dB !) */
255 static int set_input_gain(struct echoaudio *chip, u16 input, int gain)
256 {
257 	if (snd_BUG_ON(input >= num_busses_in(chip)))
258 		return -EINVAL;
259 
260 	if (wait_handshake(chip))
261 		return -EIO;
262 
263 	chip->input_gain[input] = gain;
264 	gain += GL20_INPUT_GAIN_MAGIC_NUMBER;
265 	chip->comm_page->line_in_level[input] = gain;
266 	return 0;
267 }
268 
269 
270 
271 /* Tell the DSP to reread the flags from the comm page */
272 static int update_flags(struct echoaudio *chip)
273 {
274 	if (wait_handshake(chip))
275 		return -EIO;
276 	clear_handshake(chip);
277 	return send_vector(chip, DSP_VC_UPDATE_FLAGS);
278 }
279 
280 
281 
282 static int set_professional_spdif(struct echoaudio *chip, char prof)
283 {
284 	DE_ACT(("set_professional_spdif %d\n", prof));
285 	if (prof)
286 		chip->comm_page->flags |=
287 			__constant_cpu_to_le32(DSP_FLAG_PROFESSIONAL_SPDIF);
288 	else
289 		chip->comm_page->flags &=
290 			~__constant_cpu_to_le32(DSP_FLAG_PROFESSIONAL_SPDIF);
291 	chip->professional_spdif = prof;
292 	return update_flags(chip);
293 }
294