1 // SPDX-License-Identifier: GPL-2.0-only
2 /****************************************************************************
3
4 Copyright Echo Digital Audio Corporation (c) 1998 - 2004
5 All rights reserved
6 www.echoaudio.com
7
8 This file is part of Echo Digital Audio's generic driver library.
9 *************************************************************************
10
11 Translation from C++ and adaptation for use in ALSA-Driver
12 were made by Giuliano Pochini <pochini@shiny.it>
13
14 ****************************************************************************/
15
16
17 static int read_dsp(struct echoaudio *chip, u32 *data);
18 static int set_professional_spdif(struct echoaudio *chip, char prof);
19 static int load_asic_generic(struct echoaudio *chip, u32 cmd, short asic);
20 static int check_asic_status(struct echoaudio *chip);
21 static int update_flags(struct echoaudio *chip);
22
23
init_hw(struct echoaudio * chip,u16 device_id,u16 subdevice_id)24 static int init_hw(struct echoaudio *chip, u16 device_id, u16 subdevice_id)
25 {
26 int err;
27
28 if (snd_BUG_ON((subdevice_id & 0xfff0) != LAYLA20))
29 return -ENODEV;
30
31 err = init_dsp_comm_page(chip);
32 if (err) {
33 dev_err(chip->card->dev,
34 "init_hw - could not initialize DSP comm page\n");
35 return err;
36 }
37
38 chip->device_id = device_id;
39 chip->subdevice_id = subdevice_id;
40 chip->bad_board = true;
41 chip->has_midi = true;
42 chip->dsp_code_to_load = FW_LAYLA20_DSP;
43 chip->input_clock_types =
44 ECHO_CLOCK_BIT_INTERNAL | ECHO_CLOCK_BIT_SPDIF |
45 ECHO_CLOCK_BIT_WORD | ECHO_CLOCK_BIT_SUPER;
46 chip->output_clock_types =
47 ECHO_CLOCK_BIT_WORD | ECHO_CLOCK_BIT_SUPER;
48
49 err = load_firmware(chip);
50 if (err < 0)
51 return err;
52 chip->bad_board = false;
53
54 return err;
55 }
56
57
58
set_mixer_defaults(struct echoaudio * chip)59 static int set_mixer_defaults(struct echoaudio *chip)
60 {
61 chip->professional_spdif = false;
62 return init_line_levels(chip);
63 }
64
65
66
detect_input_clocks(const struct echoaudio * chip)67 static u32 detect_input_clocks(const struct echoaudio *chip)
68 {
69 u32 clocks_from_dsp, clock_bits;
70
71 /* Map the DSP clock detect bits to the generic driver clock detect bits */
72 clocks_from_dsp = le32_to_cpu(chip->comm_page->status_clocks);
73
74 clock_bits = ECHO_CLOCK_BIT_INTERNAL;
75
76 if (clocks_from_dsp & GLDM_CLOCK_DETECT_BIT_SPDIF)
77 clock_bits |= ECHO_CLOCK_BIT_SPDIF;
78
79 if (clocks_from_dsp & GLDM_CLOCK_DETECT_BIT_WORD) {
80 if (clocks_from_dsp & GLDM_CLOCK_DETECT_BIT_SUPER)
81 clock_bits |= ECHO_CLOCK_BIT_SUPER;
82 else
83 clock_bits |= ECHO_CLOCK_BIT_WORD;
84 }
85
86 return clock_bits;
87 }
88
89
90
91 /* ASIC status check - some cards have one or two ASICs that need to be
92 loaded. Once that load is complete, this function is called to see if
93 the load was successful.
94 If this load fails, it does not necessarily mean that the hardware is
95 defective - the external box may be disconnected or turned off.
96 This routine sometimes fails for Layla20; for Layla20, the loop runs
97 5 times and succeeds if it wins on three of the loops. */
check_asic_status(struct echoaudio * chip)98 static int check_asic_status(struct echoaudio *chip)
99 {
100 u32 asic_status;
101 int goodcnt, i;
102
103 chip->asic_loaded = false;
104 for (i = goodcnt = 0; i < 5; i++) {
105 send_vector(chip, DSP_VC_TEST_ASIC);
106
107 /* The DSP will return a value to indicate whether or not
108 the ASIC is currently loaded */
109 if (read_dsp(chip, &asic_status) < 0) {
110 dev_err(chip->card->dev,
111 "check_asic_status: failed on read_dsp\n");
112 return -EIO;
113 }
114
115 if (asic_status == ASIC_ALREADY_LOADED) {
116 if (++goodcnt == 3) {
117 chip->asic_loaded = true;
118 return 0;
119 }
120 }
121 }
122 return -EIO;
123 }
124
125
126
127 /* Layla20 has an ASIC in the external box */
load_asic(struct echoaudio * chip)128 static int load_asic(struct echoaudio *chip)
129 {
130 int err;
131
132 if (chip->asic_loaded)
133 return 0;
134
135 err = load_asic_generic(chip, DSP_FNC_LOAD_LAYLA_ASIC,
136 FW_LAYLA20_ASIC);
137 if (err < 0)
138 return err;
139
140 /* Check if ASIC is alive and well. */
141 return check_asic_status(chip);
142 }
143
144
145
set_sample_rate(struct echoaudio * chip,u32 rate)146 static int set_sample_rate(struct echoaudio *chip, u32 rate)
147 {
148 if (snd_BUG_ON(rate < 8000 || rate > 50000))
149 return -EINVAL;
150
151 /* Only set the clock for internal mode. Do not return failure,
152 simply treat it as a non-event. */
153 if (chip->input_clock != ECHO_CLOCK_INTERNAL) {
154 dev_warn(chip->card->dev,
155 "Cannot set sample rate - clock not set to CLK_CLOCKININTERNAL\n");
156 chip->comm_page->sample_rate = cpu_to_le32(rate);
157 chip->sample_rate = rate;
158 return 0;
159 }
160
161 if (wait_handshake(chip))
162 return -EIO;
163
164 dev_dbg(chip->card->dev, "set_sample_rate(%d)\n", rate);
165 chip->sample_rate = rate;
166 chip->comm_page->sample_rate = cpu_to_le32(rate);
167 clear_handshake(chip);
168 return send_vector(chip, DSP_VC_SET_LAYLA_SAMPLE_RATE);
169 }
170
171
172
set_input_clock(struct echoaudio * chip,u16 clock_source)173 static int set_input_clock(struct echoaudio *chip, u16 clock_source)
174 {
175 u16 clock;
176 u32 rate;
177
178 rate = 0;
179 switch (clock_source) {
180 case ECHO_CLOCK_INTERNAL:
181 rate = chip->sample_rate;
182 clock = LAYLA20_CLOCK_INTERNAL;
183 break;
184 case ECHO_CLOCK_SPDIF:
185 clock = LAYLA20_CLOCK_SPDIF;
186 break;
187 case ECHO_CLOCK_WORD:
188 clock = LAYLA20_CLOCK_WORD;
189 break;
190 case ECHO_CLOCK_SUPER:
191 clock = LAYLA20_CLOCK_SUPER;
192 break;
193 default:
194 dev_err(chip->card->dev,
195 "Input clock 0x%x not supported for Layla24\n",
196 clock_source);
197 return -EINVAL;
198 }
199 chip->input_clock = clock_source;
200
201 chip->comm_page->input_clock = cpu_to_le16(clock);
202 clear_handshake(chip);
203 send_vector(chip, DSP_VC_UPDATE_CLOCKS);
204
205 if (rate)
206 set_sample_rate(chip, rate);
207
208 return 0;
209 }
210
211
212
set_output_clock(struct echoaudio * chip,u16 clock)213 static int set_output_clock(struct echoaudio *chip, u16 clock)
214 {
215 switch (clock) {
216 case ECHO_CLOCK_SUPER:
217 clock = LAYLA20_OUTPUT_CLOCK_SUPER;
218 break;
219 case ECHO_CLOCK_WORD:
220 clock = LAYLA20_OUTPUT_CLOCK_WORD;
221 break;
222 default:
223 dev_err(chip->card->dev, "set_output_clock wrong clock\n");
224 return -EINVAL;
225 }
226
227 if (wait_handshake(chip))
228 return -EIO;
229
230 chip->comm_page->output_clock = cpu_to_le16(clock);
231 chip->output_clock = clock;
232 clear_handshake(chip);
233 return send_vector(chip, DSP_VC_UPDATE_CLOCKS);
234 }
235
236
237
238 /* Set input bus gain (one unit is 0.5dB !) */
set_input_gain(struct echoaudio * chip,u16 input,int gain)239 static int set_input_gain(struct echoaudio *chip, u16 input, int gain)
240 {
241 if (snd_BUG_ON(input >= num_busses_in(chip)))
242 return -EINVAL;
243
244 if (wait_handshake(chip))
245 return -EIO;
246
247 chip->input_gain[input] = gain;
248 gain += GL20_INPUT_GAIN_MAGIC_NUMBER;
249 chip->comm_page->line_in_level[input] = gain;
250 return 0;
251 }
252
253
254
255 /* Tell the DSP to reread the flags from the comm page */
update_flags(struct echoaudio * chip)256 static int update_flags(struct echoaudio *chip)
257 {
258 if (wait_handshake(chip))
259 return -EIO;
260 clear_handshake(chip);
261 return send_vector(chip, DSP_VC_UPDATE_FLAGS);
262 }
263
264
265
set_professional_spdif(struct echoaudio * chip,char prof)266 static int set_professional_spdif(struct echoaudio *chip, char prof)
267 {
268 if (prof)
269 chip->comm_page->flags |=
270 cpu_to_le32(DSP_FLAG_PROFESSIONAL_SPDIF);
271 else
272 chip->comm_page->flags &=
273 ~cpu_to_le32(DSP_FLAG_PROFESSIONAL_SPDIF);
274 chip->professional_spdif = prof;
275 return update_flags(chip);
276 }
277