1 | // SPDX-License-Identifier: GPL-2.0-or-later |
2 | /* |
3 | * Copyright (c) by Jaroslav Kysela <perex@perex.cz>, |
4 | * Takashi Iwai <tiwai@suse.de> |
5 | * Lee Revell <rlrevell@joe-job.com> |
6 | * James Courtier-Dutton <James@superbug.co.uk> |
7 | * Oswald Buddenhagen <oswald.buddenhagen@gmx.de> |
8 | * Creative Labs, Inc. |
9 | * |
10 | * Routines for control of EMU10K1 chips / mixer routines |
11 | */ |
12 | |
13 | #include <linux/time.h> |
14 | #include <linux/init.h> |
15 | #include <sound/core.h> |
16 | #include <sound/emu10k1.h> |
17 | #include <linux/delay.h> |
18 | #include <sound/tlv.h> |
19 | |
20 | #include "p17v.h" |
21 | |
22 | #define AC97_ID_STAC9758 0x83847658 |
23 | |
24 | static const DECLARE_TLV_DB_SCALE(snd_audigy_db_scale2, -10350, 50, 1); /* WM8775 gain scale */ |
25 | |
26 | |
27 | static int add_ctls(struct snd_emu10k1 *emu, const struct snd_kcontrol_new *tpl, |
28 | const char * const *ctls, unsigned nctls) |
29 | { |
30 | struct snd_kcontrol_new kctl = *tpl; |
31 | int err; |
32 | |
33 | for (unsigned i = 0; i < nctls; i++) { |
34 | kctl.name = ctls[i]; |
35 | kctl.private_value = i; |
36 | err = snd_ctl_add(card: emu->card, kcontrol: snd_ctl_new1(kcontrolnew: &kctl, private_data: emu)); |
37 | if (err < 0) |
38 | return err; |
39 | } |
40 | return 0; |
41 | } |
42 | |
43 | |
44 | static int snd_emu10k1_spdif_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo) |
45 | { |
46 | uinfo->type = SNDRV_CTL_ELEM_TYPE_IEC958; |
47 | uinfo->count = 1; |
48 | return 0; |
49 | } |
50 | |
51 | static int snd_emu10k1_spdif_get(struct snd_kcontrol *kcontrol, |
52 | struct snd_ctl_elem_value *ucontrol) |
53 | { |
54 | struct snd_emu10k1 *emu = snd_kcontrol_chip(kcontrol); |
55 | unsigned int idx = snd_ctl_get_ioffidx(kctl: kcontrol, id: &ucontrol->id); |
56 | |
57 | /* Limit: emu->spdif_bits */ |
58 | if (idx >= 3) |
59 | return -EINVAL; |
60 | ucontrol->value.iec958.status[0] = (emu->spdif_bits[idx] >> 0) & 0xff; |
61 | ucontrol->value.iec958.status[1] = (emu->spdif_bits[idx] >> 8) & 0xff; |
62 | ucontrol->value.iec958.status[2] = (emu->spdif_bits[idx] >> 16) & 0xff; |
63 | ucontrol->value.iec958.status[3] = (emu->spdif_bits[idx] >> 24) & 0xff; |
64 | return 0; |
65 | } |
66 | |
67 | static int snd_emu10k1_spdif_get_mask(struct snd_kcontrol *kcontrol, |
68 | struct snd_ctl_elem_value *ucontrol) |
69 | { |
70 | ucontrol->value.iec958.status[0] = 0xff; |
71 | ucontrol->value.iec958.status[1] = 0xff; |
72 | ucontrol->value.iec958.status[2] = 0xff; |
73 | ucontrol->value.iec958.status[3] = 0xff; |
74 | return 0; |
75 | } |
76 | |
77 | #define PAIR_PS(base, one, two, sfx) base " " one sfx, base " " two sfx |
78 | #define LR_PS(base, sfx) PAIR_PS(base, "Left", "Right", sfx) |
79 | |
80 | #define ADAT_PS(pfx, sfx) \ |
81 | pfx "ADAT 0" sfx, pfx "ADAT 1" sfx, pfx "ADAT 2" sfx, pfx "ADAT 3" sfx, \ |
82 | pfx "ADAT 4" sfx, pfx "ADAT 5" sfx, pfx "ADAT 6" sfx, pfx "ADAT 7" sfx |
83 | |
84 | #define PAIR_REGS(base, one, two) \ |
85 | base ## one ## 1, \ |
86 | base ## two ## 1 |
87 | |
88 | #define LR_REGS(base) PAIR_REGS(base, _LEFT, _RIGHT) |
89 | |
90 | #define ADAT_REGS(base) \ |
91 | base+0, base+1, base+2, base+3, base+4, base+5, base+6, base+7 |
92 | |
93 | /* |
94 | * List of data sources available for each destination |
95 | */ |
96 | |
97 | #define DSP_TEXTS \ |
98 | "DSP 0", "DSP 1", "DSP 2", "DSP 3", "DSP 4", "DSP 5", "DSP 6", "DSP 7", \ |
99 | "DSP 8", "DSP 9", "DSP 10", "DSP 11", "DSP 12", "DSP 13", "DSP 14", "DSP 15", \ |
100 | "DSP 16", "DSP 17", "DSP 18", "DSP 19", "DSP 20", "DSP 21", "DSP 22", "DSP 23", \ |
101 | "DSP 24", "DSP 25", "DSP 26", "DSP 27", "DSP 28", "DSP 29", "DSP 30", "DSP 31" |
102 | |
103 | #define PAIR_TEXTS(base, one, two) PAIR_PS(base, one, two, "") |
104 | #define LR_TEXTS(base) LR_PS(base, "") |
105 | #define ADAT_TEXTS(pfx) ADAT_PS(pfx, "") |
106 | |
107 | #define EMU32_SRC_REGS \ |
108 | EMU_SRC_ALICE_EMU32A, \ |
109 | EMU_SRC_ALICE_EMU32A+1, \ |
110 | EMU_SRC_ALICE_EMU32A+2, \ |
111 | EMU_SRC_ALICE_EMU32A+3, \ |
112 | EMU_SRC_ALICE_EMU32A+4, \ |
113 | EMU_SRC_ALICE_EMU32A+5, \ |
114 | EMU_SRC_ALICE_EMU32A+6, \ |
115 | EMU_SRC_ALICE_EMU32A+7, \ |
116 | EMU_SRC_ALICE_EMU32A+8, \ |
117 | EMU_SRC_ALICE_EMU32A+9, \ |
118 | EMU_SRC_ALICE_EMU32A+0xa, \ |
119 | EMU_SRC_ALICE_EMU32A+0xb, \ |
120 | EMU_SRC_ALICE_EMU32A+0xc, \ |
121 | EMU_SRC_ALICE_EMU32A+0xd, \ |
122 | EMU_SRC_ALICE_EMU32A+0xe, \ |
123 | EMU_SRC_ALICE_EMU32A+0xf, \ |
124 | EMU_SRC_ALICE_EMU32B, \ |
125 | EMU_SRC_ALICE_EMU32B+1, \ |
126 | EMU_SRC_ALICE_EMU32B+2, \ |
127 | EMU_SRC_ALICE_EMU32B+3, \ |
128 | EMU_SRC_ALICE_EMU32B+4, \ |
129 | EMU_SRC_ALICE_EMU32B+5, \ |
130 | EMU_SRC_ALICE_EMU32B+6, \ |
131 | EMU_SRC_ALICE_EMU32B+7, \ |
132 | EMU_SRC_ALICE_EMU32B+8, \ |
133 | EMU_SRC_ALICE_EMU32B+9, \ |
134 | EMU_SRC_ALICE_EMU32B+0xa, \ |
135 | EMU_SRC_ALICE_EMU32B+0xb, \ |
136 | EMU_SRC_ALICE_EMU32B+0xc, \ |
137 | EMU_SRC_ALICE_EMU32B+0xd, \ |
138 | EMU_SRC_ALICE_EMU32B+0xe, \ |
139 | EMU_SRC_ALICE_EMU32B+0xf |
140 | |
141 | /* 1010 rev1 */ |
142 | |
143 | #define EMU1010_COMMON_TEXTS \ |
144 | "Silence", \ |
145 | PAIR_TEXTS("Dock Mic", "A", "B"), \ |
146 | LR_TEXTS("Dock ADC1"), \ |
147 | LR_TEXTS("Dock ADC2"), \ |
148 | LR_TEXTS("Dock ADC3"), \ |
149 | LR_TEXTS("0202 ADC"), \ |
150 | LR_TEXTS("1010 SPDIF"), \ |
151 | ADAT_TEXTS("1010 ") |
152 | |
153 | static const char * const emu1010_src_texts[] = { |
154 | EMU1010_COMMON_TEXTS, |
155 | DSP_TEXTS, |
156 | }; |
157 | |
158 | static const unsigned short emu1010_src_regs[] = { |
159 | EMU_SRC_SILENCE, |
160 | PAIR_REGS(EMU_SRC_DOCK_MIC, _A, _B), |
161 | LR_REGS(EMU_SRC_DOCK_ADC1), |
162 | LR_REGS(EMU_SRC_DOCK_ADC2), |
163 | LR_REGS(EMU_SRC_DOCK_ADC3), |
164 | LR_REGS(EMU_SRC_HAMOA_ADC), |
165 | LR_REGS(EMU_SRC_HANA_SPDIF), |
166 | ADAT_REGS(EMU_SRC_HANA_ADAT), |
167 | EMU32_SRC_REGS, |
168 | }; |
169 | static_assert(ARRAY_SIZE(emu1010_src_regs) == ARRAY_SIZE(emu1010_src_texts)); |
170 | |
171 | /* 1010 rev2 */ |
172 | |
173 | #define EMU1010b_COMMON_TEXTS \ |
174 | "Silence", \ |
175 | PAIR_TEXTS("Dock Mic", "A", "B"), \ |
176 | LR_TEXTS("Dock ADC1"), \ |
177 | LR_TEXTS("Dock ADC2"), \ |
178 | LR_TEXTS("0202 ADC"), \ |
179 | LR_TEXTS("Dock SPDIF"), \ |
180 | LR_TEXTS("1010 SPDIF"), \ |
181 | ADAT_TEXTS("Dock "), \ |
182 | ADAT_TEXTS("1010 ") |
183 | |
184 | static const char * const emu1010b_src_texts[] = { |
185 | EMU1010b_COMMON_TEXTS, |
186 | DSP_TEXTS, |
187 | }; |
188 | |
189 | static const unsigned short emu1010b_src_regs[] = { |
190 | EMU_SRC_SILENCE, |
191 | PAIR_REGS(EMU_SRC_DOCK_MIC, _A, _B), |
192 | LR_REGS(EMU_SRC_DOCK_ADC1), |
193 | LR_REGS(EMU_SRC_DOCK_ADC2), |
194 | LR_REGS(EMU_SRC_HAMOA_ADC), |
195 | LR_REGS(EMU_SRC_MDOCK_SPDIF), |
196 | LR_REGS(EMU_SRC_HANA_SPDIF), |
197 | ADAT_REGS(EMU_SRC_MDOCK_ADAT), |
198 | ADAT_REGS(EMU_SRC_HANA_ADAT), |
199 | EMU32_SRC_REGS, |
200 | }; |
201 | static_assert(ARRAY_SIZE(emu1010b_src_regs) == ARRAY_SIZE(emu1010b_src_texts)); |
202 | |
203 | /* 1616(m) cardbus */ |
204 | |
205 | #define EMU1616_COMMON_TEXTS \ |
206 | "Silence", \ |
207 | PAIR_TEXTS("Mic", "A", "B"), \ |
208 | LR_TEXTS("ADC1"), \ |
209 | LR_TEXTS("ADC2"), \ |
210 | LR_TEXTS("SPDIF"), \ |
211 | ADAT_TEXTS("") |
212 | |
213 | static const char * const emu1616_src_texts[] = { |
214 | EMU1616_COMMON_TEXTS, |
215 | DSP_TEXTS, |
216 | }; |
217 | |
218 | static const unsigned short emu1616_src_regs[] = { |
219 | EMU_SRC_SILENCE, |
220 | PAIR_REGS(EMU_SRC_DOCK_MIC, _A, _B), |
221 | LR_REGS(EMU_SRC_DOCK_ADC1), |
222 | LR_REGS(EMU_SRC_DOCK_ADC2), |
223 | LR_REGS(EMU_SRC_MDOCK_SPDIF), |
224 | ADAT_REGS(EMU_SRC_MDOCK_ADAT), |
225 | EMU32_SRC_REGS, |
226 | }; |
227 | static_assert(ARRAY_SIZE(emu1616_src_regs) == ARRAY_SIZE(emu1616_src_texts)); |
228 | |
229 | /* 0404 rev1 & rev2 */ |
230 | |
231 | #define EMU0404_COMMON_TEXTS \ |
232 | "Silence", \ |
233 | LR_TEXTS("ADC"), \ |
234 | LR_TEXTS("SPDIF") |
235 | |
236 | static const char * const emu0404_src_texts[] = { |
237 | EMU0404_COMMON_TEXTS, |
238 | DSP_TEXTS, |
239 | }; |
240 | |
241 | static const unsigned short emu0404_src_regs[] = { |
242 | EMU_SRC_SILENCE, |
243 | LR_REGS(EMU_SRC_HAMOA_ADC), |
244 | LR_REGS(EMU_SRC_HANA_SPDIF), |
245 | EMU32_SRC_REGS, |
246 | }; |
247 | static_assert(ARRAY_SIZE(emu0404_src_regs) == ARRAY_SIZE(emu0404_src_texts)); |
248 | |
249 | /* |
250 | * Data destinations - physical EMU outputs. |
251 | * Each destination has an enum mixer control to choose a data source |
252 | */ |
253 | |
254 | #define LR_CTLS(base) LR_PS(base, " Playback Enum") |
255 | #define ADAT_CTLS(pfx) ADAT_PS(pfx, " Playback Enum") |
256 | |
257 | /* 1010 rev1 */ |
258 | |
259 | static const char * const emu1010_output_texts[] = { |
260 | LR_CTLS("Dock DAC1" ), |
261 | LR_CTLS("Dock DAC2" ), |
262 | LR_CTLS("Dock DAC3" ), |
263 | LR_CTLS("Dock DAC4" ), |
264 | LR_CTLS("Dock Phones" ), |
265 | LR_CTLS("Dock SPDIF" ), |
266 | LR_CTLS("0202 DAC" ), |
267 | LR_CTLS("1010 SPDIF" ), |
268 | ADAT_CTLS("1010 " ), |
269 | }; |
270 | static_assert(ARRAY_SIZE(emu1010_output_texts) <= NUM_OUTPUT_DESTS); |
271 | |
272 | static const unsigned short emu1010_output_dst[] = { |
273 | LR_REGS(EMU_DST_DOCK_DAC1), |
274 | LR_REGS(EMU_DST_DOCK_DAC2), |
275 | LR_REGS(EMU_DST_DOCK_DAC3), |
276 | LR_REGS(EMU_DST_DOCK_DAC4), |
277 | LR_REGS(EMU_DST_DOCK_PHONES), |
278 | LR_REGS(EMU_DST_DOCK_SPDIF), |
279 | LR_REGS(EMU_DST_HAMOA_DAC), |
280 | LR_REGS(EMU_DST_HANA_SPDIF), |
281 | ADAT_REGS(EMU_DST_HANA_ADAT), |
282 | }; |
283 | static_assert(ARRAY_SIZE(emu1010_output_dst) == ARRAY_SIZE(emu1010_output_texts)); |
284 | |
285 | static const unsigned short emu1010_output_dflt[] = { |
286 | EMU_SRC_ALICE_EMU32A+0, EMU_SRC_ALICE_EMU32A+1, |
287 | EMU_SRC_ALICE_EMU32A+2, EMU_SRC_ALICE_EMU32A+3, |
288 | EMU_SRC_ALICE_EMU32A+4, EMU_SRC_ALICE_EMU32A+5, |
289 | EMU_SRC_ALICE_EMU32A+6, EMU_SRC_ALICE_EMU32A+7, |
290 | EMU_SRC_ALICE_EMU32A+0, EMU_SRC_ALICE_EMU32A+1, |
291 | EMU_SRC_ALICE_EMU32A+0, EMU_SRC_ALICE_EMU32A+1, |
292 | EMU_SRC_ALICE_EMU32A+0, EMU_SRC_ALICE_EMU32A+1, |
293 | EMU_SRC_ALICE_EMU32A+0, EMU_SRC_ALICE_EMU32A+1, |
294 | EMU_SRC_ALICE_EMU32A+0, EMU_SRC_ALICE_EMU32A+1, EMU_SRC_ALICE_EMU32A+2, EMU_SRC_ALICE_EMU32A+3, |
295 | EMU_SRC_ALICE_EMU32A+4, EMU_SRC_ALICE_EMU32A+5, EMU_SRC_ALICE_EMU32A+6, EMU_SRC_ALICE_EMU32A+7, |
296 | }; |
297 | static_assert(ARRAY_SIZE(emu1010_output_dflt) == ARRAY_SIZE(emu1010_output_dst)); |
298 | |
299 | /* 1010 rev2 */ |
300 | |
301 | static const char * const snd_emu1010b_output_texts[] = { |
302 | LR_CTLS("Dock DAC1" ), |
303 | LR_CTLS("Dock DAC2" ), |
304 | LR_CTLS("Dock DAC3" ), |
305 | LR_CTLS("Dock SPDIF" ), |
306 | ADAT_CTLS("Dock " ), |
307 | LR_CTLS("0202 DAC" ), |
308 | LR_CTLS("1010 SPDIF" ), |
309 | ADAT_CTLS("1010 " ), |
310 | }; |
311 | static_assert(ARRAY_SIZE(snd_emu1010b_output_texts) <= NUM_OUTPUT_DESTS); |
312 | |
313 | static const unsigned short emu1010b_output_dst[] = { |
314 | LR_REGS(EMU_DST_DOCK_DAC1), |
315 | LR_REGS(EMU_DST_DOCK_DAC2), |
316 | LR_REGS(EMU_DST_DOCK_DAC3), |
317 | LR_REGS(EMU_DST_MDOCK_SPDIF), |
318 | ADAT_REGS(EMU_DST_MDOCK_ADAT), |
319 | LR_REGS(EMU_DST_HAMOA_DAC), |
320 | LR_REGS(EMU_DST_HANA_SPDIF), |
321 | ADAT_REGS(EMU_DST_HANA_ADAT), |
322 | }; |
323 | static_assert(ARRAY_SIZE(emu1010b_output_dst) == ARRAY_SIZE(snd_emu1010b_output_texts)); |
324 | |
325 | static const unsigned short emu1010b_output_dflt[] = { |
326 | EMU_SRC_ALICE_EMU32A+0, EMU_SRC_ALICE_EMU32A+1, |
327 | EMU_SRC_ALICE_EMU32A+2, EMU_SRC_ALICE_EMU32A+3, |
328 | EMU_SRC_ALICE_EMU32A+4, EMU_SRC_ALICE_EMU32A+5, |
329 | EMU_SRC_ALICE_EMU32A+0, EMU_SRC_ALICE_EMU32A+1, |
330 | EMU_SRC_ALICE_EMU32A+0, EMU_SRC_ALICE_EMU32A+1, EMU_SRC_ALICE_EMU32A+2, EMU_SRC_ALICE_EMU32A+3, |
331 | EMU_SRC_ALICE_EMU32A+4, EMU_SRC_ALICE_EMU32A+5, EMU_SRC_ALICE_EMU32A+6, EMU_SRC_ALICE_EMU32A+7, |
332 | EMU_SRC_ALICE_EMU32A+0, EMU_SRC_ALICE_EMU32A+1, |
333 | EMU_SRC_ALICE_EMU32A+0, EMU_SRC_ALICE_EMU32A+1, |
334 | EMU_SRC_ALICE_EMU32A+0, EMU_SRC_ALICE_EMU32A+1, EMU_SRC_ALICE_EMU32A+2, EMU_SRC_ALICE_EMU32A+3, |
335 | EMU_SRC_ALICE_EMU32A+4, EMU_SRC_ALICE_EMU32A+5, EMU_SRC_ALICE_EMU32A+6, EMU_SRC_ALICE_EMU32A+7, |
336 | }; |
337 | |
338 | /* 1616(m) cardbus */ |
339 | |
340 | static const char * const snd_emu1616_output_texts[] = { |
341 | LR_CTLS("Dock DAC1" ), |
342 | LR_CTLS("Dock DAC2" ), |
343 | LR_CTLS("Dock DAC3" ), |
344 | LR_CTLS("Dock SPDIF" ), |
345 | ADAT_CTLS("Dock " ), |
346 | LR_CTLS("Mana DAC" ), |
347 | }; |
348 | static_assert(ARRAY_SIZE(snd_emu1616_output_texts) <= NUM_OUTPUT_DESTS); |
349 | |
350 | static const unsigned short emu1616_output_dst[] = { |
351 | LR_REGS(EMU_DST_DOCK_DAC1), |
352 | LR_REGS(EMU_DST_DOCK_DAC2), |
353 | LR_REGS(EMU_DST_DOCK_DAC3), |
354 | LR_REGS(EMU_DST_MDOCK_SPDIF), |
355 | ADAT_REGS(EMU_DST_MDOCK_ADAT), |
356 | EMU_DST_MANA_DAC_LEFT, EMU_DST_MANA_DAC_RIGHT, |
357 | }; |
358 | static_assert(ARRAY_SIZE(emu1616_output_dst) == ARRAY_SIZE(snd_emu1616_output_texts)); |
359 | |
360 | static const unsigned short emu1616_output_dflt[] = { |
361 | EMU_SRC_ALICE_EMU32A+0, EMU_SRC_ALICE_EMU32A+1, |
362 | EMU_SRC_ALICE_EMU32A+2, EMU_SRC_ALICE_EMU32A+3, |
363 | EMU_SRC_ALICE_EMU32A+4, EMU_SRC_ALICE_EMU32A+5, |
364 | EMU_SRC_ALICE_EMU32A+0, EMU_SRC_ALICE_EMU32A+1, |
365 | EMU_SRC_ALICE_EMU32A+0, EMU_SRC_ALICE_EMU32A+1, EMU_SRC_ALICE_EMU32A+2, EMU_SRC_ALICE_EMU32A+3, |
366 | EMU_SRC_ALICE_EMU32A+4, EMU_SRC_ALICE_EMU32A+5, EMU_SRC_ALICE_EMU32A+6, EMU_SRC_ALICE_EMU32A+7, |
367 | EMU_SRC_ALICE_EMU32A+0, EMU_SRC_ALICE_EMU32A+1, |
368 | }; |
369 | static_assert(ARRAY_SIZE(emu1616_output_dflt) == ARRAY_SIZE(emu1616_output_dst)); |
370 | |
371 | /* 0404 rev1 & rev2 */ |
372 | |
373 | static const char * const snd_emu0404_output_texts[] = { |
374 | LR_CTLS("DAC" ), |
375 | LR_CTLS("SPDIF" ), |
376 | }; |
377 | static_assert(ARRAY_SIZE(snd_emu0404_output_texts) <= NUM_OUTPUT_DESTS); |
378 | |
379 | static const unsigned short emu0404_output_dst[] = { |
380 | LR_REGS(EMU_DST_HAMOA_DAC), |
381 | LR_REGS(EMU_DST_HANA_SPDIF), |
382 | }; |
383 | static_assert(ARRAY_SIZE(emu0404_output_dst) == ARRAY_SIZE(snd_emu0404_output_texts)); |
384 | |
385 | static const unsigned short emu0404_output_dflt[] = { |
386 | EMU_SRC_ALICE_EMU32A+0, EMU_SRC_ALICE_EMU32A+1, |
387 | EMU_SRC_ALICE_EMU32A+0, EMU_SRC_ALICE_EMU32A+1, |
388 | }; |
389 | static_assert(ARRAY_SIZE(emu0404_output_dflt) == ARRAY_SIZE(emu0404_output_dst)); |
390 | |
391 | /* |
392 | * Data destinations - FPGA outputs going to Alice2 (Audigy) for |
393 | * capture (EMU32 + I2S links) |
394 | * Each destination has an enum mixer control to choose a data source |
395 | */ |
396 | |
397 | static const char * const emu1010_input_texts[] = { |
398 | "DSP 0 Capture Enum" , |
399 | "DSP 1 Capture Enum" , |
400 | "DSP 2 Capture Enum" , |
401 | "DSP 3 Capture Enum" , |
402 | "DSP 4 Capture Enum" , |
403 | "DSP 5 Capture Enum" , |
404 | "DSP 6 Capture Enum" , |
405 | "DSP 7 Capture Enum" , |
406 | "DSP 8 Capture Enum" , |
407 | "DSP 9 Capture Enum" , |
408 | "DSP A Capture Enum" , |
409 | "DSP B Capture Enum" , |
410 | "DSP C Capture Enum" , |
411 | "DSP D Capture Enum" , |
412 | "DSP E Capture Enum" , |
413 | "DSP F Capture Enum" , |
414 | /* These exist only on rev1 EMU1010 cards. */ |
415 | "DSP 10 Capture Enum" , |
416 | "DSP 11 Capture Enum" , |
417 | "DSP 12 Capture Enum" , |
418 | "DSP 13 Capture Enum" , |
419 | "DSP 14 Capture Enum" , |
420 | "DSP 15 Capture Enum" , |
421 | }; |
422 | static_assert(ARRAY_SIZE(emu1010_input_texts) <= NUM_INPUT_DESTS); |
423 | |
424 | static const unsigned short emu1010_input_dst[] = { |
425 | EMU_DST_ALICE2_EMU32_0, |
426 | EMU_DST_ALICE2_EMU32_1, |
427 | EMU_DST_ALICE2_EMU32_2, |
428 | EMU_DST_ALICE2_EMU32_3, |
429 | EMU_DST_ALICE2_EMU32_4, |
430 | EMU_DST_ALICE2_EMU32_5, |
431 | EMU_DST_ALICE2_EMU32_6, |
432 | EMU_DST_ALICE2_EMU32_7, |
433 | EMU_DST_ALICE2_EMU32_8, |
434 | EMU_DST_ALICE2_EMU32_9, |
435 | EMU_DST_ALICE2_EMU32_A, |
436 | EMU_DST_ALICE2_EMU32_B, |
437 | EMU_DST_ALICE2_EMU32_C, |
438 | EMU_DST_ALICE2_EMU32_D, |
439 | EMU_DST_ALICE2_EMU32_E, |
440 | EMU_DST_ALICE2_EMU32_F, |
441 | /* These exist only on rev1 EMU1010 cards. */ |
442 | EMU_DST_ALICE_I2S0_LEFT, |
443 | EMU_DST_ALICE_I2S0_RIGHT, |
444 | EMU_DST_ALICE_I2S1_LEFT, |
445 | EMU_DST_ALICE_I2S1_RIGHT, |
446 | EMU_DST_ALICE_I2S2_LEFT, |
447 | EMU_DST_ALICE_I2S2_RIGHT, |
448 | }; |
449 | static_assert(ARRAY_SIZE(emu1010_input_dst) == ARRAY_SIZE(emu1010_input_texts)); |
450 | |
451 | static const unsigned short emu1010_input_dflt[] = { |
452 | EMU_SRC_DOCK_MIC_A1, |
453 | EMU_SRC_DOCK_MIC_B1, |
454 | EMU_SRC_HAMOA_ADC_LEFT1, |
455 | EMU_SRC_HAMOA_ADC_RIGHT1, |
456 | EMU_SRC_DOCK_ADC1_LEFT1, |
457 | EMU_SRC_DOCK_ADC1_RIGHT1, |
458 | EMU_SRC_DOCK_ADC2_LEFT1, |
459 | EMU_SRC_DOCK_ADC2_RIGHT1, |
460 | /* Pavel Hofman - setting defaults for all capture channels. |
461 | * Defaults only, users will set their own values anyways, let's |
462 | * just copy/paste. */ |
463 | EMU_SRC_DOCK_MIC_A1, |
464 | EMU_SRC_DOCK_MIC_B1, |
465 | EMU_SRC_HAMOA_ADC_LEFT1, |
466 | EMU_SRC_HAMOA_ADC_RIGHT1, |
467 | EMU_SRC_DOCK_ADC1_LEFT1, |
468 | EMU_SRC_DOCK_ADC1_RIGHT1, |
469 | EMU_SRC_DOCK_ADC2_LEFT1, |
470 | EMU_SRC_DOCK_ADC2_RIGHT1, |
471 | |
472 | EMU_SRC_DOCK_ADC1_LEFT1, |
473 | EMU_SRC_DOCK_ADC1_RIGHT1, |
474 | EMU_SRC_DOCK_ADC2_LEFT1, |
475 | EMU_SRC_DOCK_ADC2_RIGHT1, |
476 | EMU_SRC_DOCK_ADC3_LEFT1, |
477 | EMU_SRC_DOCK_ADC3_RIGHT1, |
478 | }; |
479 | static_assert(ARRAY_SIZE(emu1010_input_dflt) == ARRAY_SIZE(emu1010_input_dst)); |
480 | |
481 | static const unsigned short emu0404_input_dflt[] = { |
482 | EMU_SRC_HAMOA_ADC_LEFT1, |
483 | EMU_SRC_HAMOA_ADC_RIGHT1, |
484 | EMU_SRC_SILENCE, |
485 | EMU_SRC_SILENCE, |
486 | EMU_SRC_SILENCE, |
487 | EMU_SRC_SILENCE, |
488 | EMU_SRC_SILENCE, |
489 | EMU_SRC_SILENCE, |
490 | EMU_SRC_HANA_SPDIF_LEFT1, |
491 | EMU_SRC_HANA_SPDIF_RIGHT1, |
492 | EMU_SRC_SILENCE, |
493 | EMU_SRC_SILENCE, |
494 | EMU_SRC_SILENCE, |
495 | EMU_SRC_SILENCE, |
496 | EMU_SRC_SILENCE, |
497 | EMU_SRC_SILENCE, |
498 | }; |
499 | |
500 | struct snd_emu1010_routing_info { |
501 | const char * const *src_texts; |
502 | const char * const *out_texts; |
503 | const unsigned short *src_regs; |
504 | const unsigned short *out_regs; |
505 | const unsigned short *in_regs; |
506 | const unsigned short *out_dflts; |
507 | const unsigned short *in_dflts; |
508 | unsigned n_srcs; |
509 | unsigned n_outs; |
510 | unsigned n_ins; |
511 | }; |
512 | |
513 | static const struct snd_emu1010_routing_info emu1010_routing_info[] = { |
514 | { |
515 | /* rev1 1010 */ |
516 | .src_regs = emu1010_src_regs, |
517 | .src_texts = emu1010_src_texts, |
518 | .n_srcs = ARRAY_SIZE(emu1010_src_texts), |
519 | |
520 | .out_dflts = emu1010_output_dflt, |
521 | .out_regs = emu1010_output_dst, |
522 | .out_texts = emu1010_output_texts, |
523 | .n_outs = ARRAY_SIZE(emu1010_output_dst), |
524 | |
525 | .in_dflts = emu1010_input_dflt, |
526 | .in_regs = emu1010_input_dst, |
527 | .n_ins = ARRAY_SIZE(emu1010_input_dst), |
528 | }, |
529 | { |
530 | /* rev2 1010 */ |
531 | .src_regs = emu1010b_src_regs, |
532 | .src_texts = emu1010b_src_texts, |
533 | .n_srcs = ARRAY_SIZE(emu1010b_src_texts), |
534 | |
535 | .out_dflts = emu1010b_output_dflt, |
536 | .out_regs = emu1010b_output_dst, |
537 | .out_texts = snd_emu1010b_output_texts, |
538 | .n_outs = ARRAY_SIZE(emu1010b_output_dst), |
539 | |
540 | .in_dflts = emu1010_input_dflt, |
541 | .in_regs = emu1010_input_dst, |
542 | .n_ins = ARRAY_SIZE(emu1010_input_dst) - 6, |
543 | }, |
544 | { |
545 | /* 1616(m) cardbus */ |
546 | .src_regs = emu1616_src_regs, |
547 | .src_texts = emu1616_src_texts, |
548 | .n_srcs = ARRAY_SIZE(emu1616_src_texts), |
549 | |
550 | .out_dflts = emu1616_output_dflt, |
551 | .out_regs = emu1616_output_dst, |
552 | .out_texts = snd_emu1616_output_texts, |
553 | .n_outs = ARRAY_SIZE(emu1616_output_dst), |
554 | |
555 | .in_dflts = emu1010_input_dflt, |
556 | .in_regs = emu1010_input_dst, |
557 | .n_ins = ARRAY_SIZE(emu1010_input_dst) - 6, |
558 | }, |
559 | { |
560 | /* 0404 */ |
561 | .src_regs = emu0404_src_regs, |
562 | .src_texts = emu0404_src_texts, |
563 | .n_srcs = ARRAY_SIZE(emu0404_src_texts), |
564 | |
565 | .out_dflts = emu0404_output_dflt, |
566 | .out_regs = emu0404_output_dst, |
567 | .out_texts = snd_emu0404_output_texts, |
568 | .n_outs = ARRAY_SIZE(emu0404_output_dflt), |
569 | |
570 | .in_dflts = emu0404_input_dflt, |
571 | .in_regs = emu1010_input_dst, |
572 | .n_ins = ARRAY_SIZE(emu1010_input_dst) - 6, |
573 | }, |
574 | }; |
575 | |
576 | static unsigned emu1010_idx(struct snd_emu10k1 *emu) |
577 | { |
578 | return emu->card_capabilities->emu_model - 1; |
579 | } |
580 | |
581 | static void snd_emu1010_output_source_apply(struct snd_emu10k1 *emu, |
582 | int channel, int src) |
583 | { |
584 | const struct snd_emu1010_routing_info *emu_ri = |
585 | &emu1010_routing_info[emu1010_idx(emu)]; |
586 | |
587 | snd_emu1010_fpga_link_dst_src_write(emu, |
588 | dst: emu_ri->out_regs[channel], src: emu_ri->src_regs[src]); |
589 | } |
590 | |
591 | static void snd_emu1010_input_source_apply(struct snd_emu10k1 *emu, |
592 | int channel, int src) |
593 | { |
594 | const struct snd_emu1010_routing_info *emu_ri = |
595 | &emu1010_routing_info[emu1010_idx(emu)]; |
596 | |
597 | snd_emu1010_fpga_link_dst_src_write(emu, |
598 | dst: emu_ri->in_regs[channel], src: emu_ri->src_regs[src]); |
599 | } |
600 | |
601 | static void snd_emu1010_apply_sources(struct snd_emu10k1 *emu) |
602 | { |
603 | const struct snd_emu1010_routing_info *emu_ri = |
604 | &emu1010_routing_info[emu1010_idx(emu)]; |
605 | |
606 | for (unsigned i = 0; i < emu_ri->n_outs; i++) |
607 | snd_emu1010_output_source_apply( |
608 | emu, channel: i, src: emu->emu1010.output_source[i]); |
609 | for (unsigned i = 0; i < emu_ri->n_ins; i++) |
610 | snd_emu1010_input_source_apply( |
611 | emu, channel: i, src: emu->emu1010.input_source[i]); |
612 | } |
613 | |
614 | static u8 emu1010_map_source(const struct snd_emu1010_routing_info *emu_ri, |
615 | unsigned val) |
616 | { |
617 | for (unsigned i = 0; i < emu_ri->n_srcs; i++) |
618 | if (val == emu_ri->src_regs[i]) |
619 | return i; |
620 | return 0; |
621 | } |
622 | |
623 | static int snd_emu1010_input_output_source_info(struct snd_kcontrol *kcontrol, |
624 | struct snd_ctl_elem_info *uinfo) |
625 | { |
626 | struct snd_emu10k1 *emu = snd_kcontrol_chip(kcontrol); |
627 | const struct snd_emu1010_routing_info *emu_ri = |
628 | &emu1010_routing_info[emu1010_idx(emu)]; |
629 | |
630 | return snd_ctl_enum_info(info: uinfo, channels: 1, items: emu_ri->n_srcs, names: emu_ri->src_texts); |
631 | } |
632 | |
633 | static int snd_emu1010_output_source_get(struct snd_kcontrol *kcontrol, |
634 | struct snd_ctl_elem_value *ucontrol) |
635 | { |
636 | struct snd_emu10k1 *emu = snd_kcontrol_chip(kcontrol); |
637 | const struct snd_emu1010_routing_info *emu_ri = |
638 | &emu1010_routing_info[emu1010_idx(emu)]; |
639 | unsigned channel = kcontrol->private_value; |
640 | |
641 | if (channel >= emu_ri->n_outs) |
642 | return -EINVAL; |
643 | ucontrol->value.enumerated.item[0] = emu->emu1010.output_source[channel]; |
644 | return 0; |
645 | } |
646 | |
647 | static int snd_emu1010_output_source_put(struct snd_kcontrol *kcontrol, |
648 | struct snd_ctl_elem_value *ucontrol) |
649 | { |
650 | struct snd_emu10k1 *emu = snd_kcontrol_chip(kcontrol); |
651 | const struct snd_emu1010_routing_info *emu_ri = |
652 | &emu1010_routing_info[emu1010_idx(emu)]; |
653 | unsigned val = ucontrol->value.enumerated.item[0]; |
654 | unsigned channel = kcontrol->private_value; |
655 | int change; |
656 | |
657 | if (val >= emu_ri->n_srcs) |
658 | return -EINVAL; |
659 | if (channel >= emu_ri->n_outs) |
660 | return -EINVAL; |
661 | change = (emu->emu1010.output_source[channel] != val); |
662 | if (change) { |
663 | emu->emu1010.output_source[channel] = val; |
664 | snd_emu1010_output_source_apply(emu, channel, src: val); |
665 | } |
666 | return change; |
667 | } |
668 | |
669 | static const struct snd_kcontrol_new emu1010_output_source_ctl = { |
670 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, |
671 | .access = SNDRV_CTL_ELEM_ACCESS_READWRITE, |
672 | .info = snd_emu1010_input_output_source_info, |
673 | .get = snd_emu1010_output_source_get, |
674 | .put = snd_emu1010_output_source_put |
675 | }; |
676 | |
677 | static int snd_emu1010_input_source_get(struct snd_kcontrol *kcontrol, |
678 | struct snd_ctl_elem_value *ucontrol) |
679 | { |
680 | struct snd_emu10k1 *emu = snd_kcontrol_chip(kcontrol); |
681 | const struct snd_emu1010_routing_info *emu_ri = |
682 | &emu1010_routing_info[emu1010_idx(emu)]; |
683 | unsigned channel = kcontrol->private_value; |
684 | |
685 | if (channel >= emu_ri->n_ins) |
686 | return -EINVAL; |
687 | ucontrol->value.enumerated.item[0] = emu->emu1010.input_source[channel]; |
688 | return 0; |
689 | } |
690 | |
691 | static int snd_emu1010_input_source_put(struct snd_kcontrol *kcontrol, |
692 | struct snd_ctl_elem_value *ucontrol) |
693 | { |
694 | struct snd_emu10k1 *emu = snd_kcontrol_chip(kcontrol); |
695 | const struct snd_emu1010_routing_info *emu_ri = |
696 | &emu1010_routing_info[emu1010_idx(emu)]; |
697 | unsigned val = ucontrol->value.enumerated.item[0]; |
698 | unsigned channel = kcontrol->private_value; |
699 | int change; |
700 | |
701 | if (val >= emu_ri->n_srcs) |
702 | return -EINVAL; |
703 | if (channel >= emu_ri->n_ins) |
704 | return -EINVAL; |
705 | change = (emu->emu1010.input_source[channel] != val); |
706 | if (change) { |
707 | emu->emu1010.input_source[channel] = val; |
708 | snd_emu1010_input_source_apply(emu, channel, src: val); |
709 | } |
710 | return change; |
711 | } |
712 | |
713 | static const struct snd_kcontrol_new emu1010_input_source_ctl = { |
714 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, |
715 | .access = SNDRV_CTL_ELEM_ACCESS_READWRITE, |
716 | .info = snd_emu1010_input_output_source_info, |
717 | .get = snd_emu1010_input_source_get, |
718 | .put = snd_emu1010_input_source_put |
719 | }; |
720 | |
721 | static int add_emu1010_source_mixers(struct snd_emu10k1 *emu) |
722 | { |
723 | const struct snd_emu1010_routing_info *emu_ri = |
724 | &emu1010_routing_info[emu1010_idx(emu)]; |
725 | int err; |
726 | |
727 | err = add_ctls(emu, tpl: &emu1010_output_source_ctl, |
728 | ctls: emu_ri->out_texts, nctls: emu_ri->n_outs); |
729 | if (err < 0) |
730 | return err; |
731 | err = add_ctls(emu, tpl: &emu1010_input_source_ctl, |
732 | ctls: emu1010_input_texts, nctls: emu_ri->n_ins); |
733 | return err; |
734 | } |
735 | |
736 | |
737 | static const char * const snd_emu1010_adc_pads[] = { |
738 | "ADC1 14dB PAD 0202 Capture Switch" , |
739 | "ADC1 14dB PAD Audio Dock Capture Switch" , |
740 | "ADC2 14dB PAD Audio Dock Capture Switch" , |
741 | "ADC3 14dB PAD Audio Dock Capture Switch" , |
742 | }; |
743 | |
744 | static const unsigned short snd_emu1010_adc_pad_regs[] = { |
745 | EMU_HANA_0202_ADC_PAD1, |
746 | EMU_HANA_DOCK_ADC_PAD1, |
747 | EMU_HANA_DOCK_ADC_PAD2, |
748 | EMU_HANA_DOCK_ADC_PAD3, |
749 | }; |
750 | |
751 | #define snd_emu1010_adc_pads_info snd_ctl_boolean_mono_info |
752 | |
753 | static int snd_emu1010_adc_pads_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) |
754 | { |
755 | struct snd_emu10k1 *emu = snd_kcontrol_chip(kcontrol); |
756 | unsigned int mask = snd_emu1010_adc_pad_regs[kcontrol->private_value]; |
757 | |
758 | ucontrol->value.integer.value[0] = (emu->emu1010.adc_pads & mask) ? 1 : 0; |
759 | return 0; |
760 | } |
761 | |
762 | static int snd_emu1010_adc_pads_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) |
763 | { |
764 | struct snd_emu10k1 *emu = snd_kcontrol_chip(kcontrol); |
765 | unsigned int mask = snd_emu1010_adc_pad_regs[kcontrol->private_value]; |
766 | unsigned int val, cache; |
767 | int change; |
768 | |
769 | val = ucontrol->value.integer.value[0]; |
770 | cache = emu->emu1010.adc_pads; |
771 | if (val == 1) |
772 | cache = cache | mask; |
773 | else |
774 | cache = cache & ~mask; |
775 | change = (cache != emu->emu1010.adc_pads); |
776 | if (change) { |
777 | snd_emu1010_fpga_write(emu, EMU_HANA_ADC_PADS, value: cache ); |
778 | emu->emu1010.adc_pads = cache; |
779 | } |
780 | |
781 | return change; |
782 | } |
783 | |
784 | static const struct snd_kcontrol_new emu1010_adc_pads_ctl = { |
785 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, |
786 | .access = SNDRV_CTL_ELEM_ACCESS_READWRITE, |
787 | .info = snd_emu1010_adc_pads_info, |
788 | .get = snd_emu1010_adc_pads_get, |
789 | .put = snd_emu1010_adc_pads_put |
790 | }; |
791 | |
792 | |
793 | static const char * const snd_emu1010_dac_pads[] = { |
794 | "DAC1 0202 14dB PAD Playback Switch" , |
795 | "DAC1 Audio Dock 14dB PAD Playback Switch" , |
796 | "DAC2 Audio Dock 14dB PAD Playback Switch" , |
797 | "DAC3 Audio Dock 14dB PAD Playback Switch" , |
798 | "DAC4 Audio Dock 14dB PAD Playback Switch" , |
799 | }; |
800 | |
801 | static const unsigned short snd_emu1010_dac_regs[] = { |
802 | EMU_HANA_0202_DAC_PAD1, |
803 | EMU_HANA_DOCK_DAC_PAD1, |
804 | EMU_HANA_DOCK_DAC_PAD2, |
805 | EMU_HANA_DOCK_DAC_PAD3, |
806 | EMU_HANA_DOCK_DAC_PAD4, |
807 | }; |
808 | |
809 | #define snd_emu1010_dac_pads_info snd_ctl_boolean_mono_info |
810 | |
811 | static int snd_emu1010_dac_pads_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) |
812 | { |
813 | struct snd_emu10k1 *emu = snd_kcontrol_chip(kcontrol); |
814 | unsigned int mask = snd_emu1010_dac_regs[kcontrol->private_value]; |
815 | |
816 | ucontrol->value.integer.value[0] = (emu->emu1010.dac_pads & mask) ? 1 : 0; |
817 | return 0; |
818 | } |
819 | |
820 | static int snd_emu1010_dac_pads_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) |
821 | { |
822 | struct snd_emu10k1 *emu = snd_kcontrol_chip(kcontrol); |
823 | unsigned int mask = snd_emu1010_dac_regs[kcontrol->private_value]; |
824 | unsigned int val, cache; |
825 | int change; |
826 | |
827 | val = ucontrol->value.integer.value[0]; |
828 | cache = emu->emu1010.dac_pads; |
829 | if (val == 1) |
830 | cache = cache | mask; |
831 | else |
832 | cache = cache & ~mask; |
833 | change = (cache != emu->emu1010.dac_pads); |
834 | if (change) { |
835 | snd_emu1010_fpga_write(emu, EMU_HANA_DAC_PADS, value: cache ); |
836 | emu->emu1010.dac_pads = cache; |
837 | } |
838 | |
839 | return change; |
840 | } |
841 | |
842 | static const struct snd_kcontrol_new emu1010_dac_pads_ctl = { |
843 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, |
844 | .access = SNDRV_CTL_ELEM_ACCESS_READWRITE, |
845 | .info = snd_emu1010_dac_pads_info, |
846 | .get = snd_emu1010_dac_pads_get, |
847 | .put = snd_emu1010_dac_pads_put |
848 | }; |
849 | |
850 | |
851 | struct snd_emu1010_pads_info { |
852 | const char * const *adc_ctls, * const *dac_ctls; |
853 | unsigned n_adc_ctls, n_dac_ctls; |
854 | }; |
855 | |
856 | static const struct snd_emu1010_pads_info emu1010_pads_info[] = { |
857 | { |
858 | /* rev1 1010 */ |
859 | .adc_ctls = snd_emu1010_adc_pads, |
860 | .n_adc_ctls = ARRAY_SIZE(snd_emu1010_adc_pads), |
861 | .dac_ctls = snd_emu1010_dac_pads, |
862 | .n_dac_ctls = ARRAY_SIZE(snd_emu1010_dac_pads), |
863 | }, |
864 | { |
865 | /* rev2 1010 */ |
866 | .adc_ctls = snd_emu1010_adc_pads, |
867 | .n_adc_ctls = ARRAY_SIZE(snd_emu1010_adc_pads) - 1, |
868 | .dac_ctls = snd_emu1010_dac_pads, |
869 | .n_dac_ctls = ARRAY_SIZE(snd_emu1010_dac_pads) - 1, |
870 | }, |
871 | { |
872 | /* 1616(m) cardbus */ |
873 | .adc_ctls = snd_emu1010_adc_pads + 1, |
874 | .n_adc_ctls = ARRAY_SIZE(snd_emu1010_adc_pads) - 2, |
875 | .dac_ctls = snd_emu1010_dac_pads + 1, |
876 | .n_dac_ctls = ARRAY_SIZE(snd_emu1010_dac_pads) - 2, |
877 | }, |
878 | { |
879 | /* 0404 */ |
880 | .adc_ctls = NULL, |
881 | .n_adc_ctls = 0, |
882 | .dac_ctls = NULL, |
883 | .n_dac_ctls = 0, |
884 | }, |
885 | }; |
886 | |
887 | static const char * const emu1010_clock_texts[] = { |
888 | "44100" , "48000" , "SPDIF" , "ADAT" , "Dock" , "BNC" |
889 | }; |
890 | |
891 | static const u8 emu1010_clock_vals[] = { |
892 | EMU_HANA_WCLOCK_INT_44_1K, |
893 | EMU_HANA_WCLOCK_INT_48K, |
894 | EMU_HANA_WCLOCK_HANA_SPDIF_IN, |
895 | EMU_HANA_WCLOCK_HANA_ADAT_IN, |
896 | EMU_HANA_WCLOCK_2ND_HANA, |
897 | EMU_HANA_WCLOCK_SYNC_BNC, |
898 | }; |
899 | |
900 | static const char * const emu0404_clock_texts[] = { |
901 | "44100" , "48000" , "SPDIF" , "BNC" |
902 | }; |
903 | |
904 | static const u8 emu0404_clock_vals[] = { |
905 | EMU_HANA_WCLOCK_INT_44_1K, |
906 | EMU_HANA_WCLOCK_INT_48K, |
907 | EMU_HANA_WCLOCK_HANA_SPDIF_IN, |
908 | EMU_HANA_WCLOCK_SYNC_BNC, |
909 | }; |
910 | |
911 | struct snd_emu1010_clock_info { |
912 | const char * const *texts; |
913 | const u8 *vals; |
914 | unsigned num; |
915 | }; |
916 | |
917 | static const struct snd_emu1010_clock_info emu1010_clock_info[] = { |
918 | { |
919 | // rev1 1010 |
920 | .texts = emu1010_clock_texts, |
921 | .vals = emu1010_clock_vals, |
922 | .num = ARRAY_SIZE(emu1010_clock_vals), |
923 | }, |
924 | { |
925 | // rev2 1010 |
926 | .texts = emu1010_clock_texts, |
927 | .vals = emu1010_clock_vals, |
928 | .num = ARRAY_SIZE(emu1010_clock_vals) - 1, |
929 | }, |
930 | { |
931 | // 1616(m) CardBus |
932 | .texts = emu1010_clock_texts, |
933 | // TODO: determine what is actually available. |
934 | // Pedantically, *every* source comes from the 2nd FPGA, as the |
935 | // card itself has no own (digital) audio ports. The user manual |
936 | // claims that ADAT and S/PDIF clock sources are separate, which |
937 | // can mean two things: either E-MU mapped the dock's sources to |
938 | // the primary ones, or they determine the meaning of the "Dock" |
939 | // source depending on how the ports are actually configured |
940 | // (which the 2nd FPGA must be doing anyway). |
941 | .vals = emu1010_clock_vals, |
942 | .num = ARRAY_SIZE(emu1010_clock_vals), |
943 | }, |
944 | { |
945 | // 0404 |
946 | .texts = emu0404_clock_texts, |
947 | .vals = emu0404_clock_vals, |
948 | .num = ARRAY_SIZE(emu0404_clock_vals), |
949 | }, |
950 | }; |
951 | |
952 | static int snd_emu1010_clock_source_info(struct snd_kcontrol *kcontrol, |
953 | struct snd_ctl_elem_info *uinfo) |
954 | { |
955 | struct snd_emu10k1 *emu = snd_kcontrol_chip(kcontrol); |
956 | const struct snd_emu1010_clock_info *emu_ci = |
957 | &emu1010_clock_info[emu1010_idx(emu)]; |
958 | |
959 | return snd_ctl_enum_info(info: uinfo, channels: 1, items: emu_ci->num, names: emu_ci->texts); |
960 | } |
961 | |
962 | static int snd_emu1010_clock_source_get(struct snd_kcontrol *kcontrol, |
963 | struct snd_ctl_elem_value *ucontrol) |
964 | { |
965 | struct snd_emu10k1 *emu = snd_kcontrol_chip(kcontrol); |
966 | |
967 | ucontrol->value.enumerated.item[0] = emu->emu1010.clock_source; |
968 | return 0; |
969 | } |
970 | |
971 | static int snd_emu1010_clock_source_put(struct snd_kcontrol *kcontrol, |
972 | struct snd_ctl_elem_value *ucontrol) |
973 | { |
974 | struct snd_emu10k1 *emu = snd_kcontrol_chip(kcontrol); |
975 | const struct snd_emu1010_clock_info *emu_ci = |
976 | &emu1010_clock_info[emu1010_idx(emu)]; |
977 | unsigned int val; |
978 | int change = 0; |
979 | |
980 | val = ucontrol->value.enumerated.item[0] ; |
981 | if (val >= emu_ci->num) |
982 | return -EINVAL; |
983 | spin_lock_irq(lock: &emu->reg_lock); |
984 | change = (emu->emu1010.clock_source != val); |
985 | if (change) { |
986 | emu->emu1010.clock_source = val; |
987 | emu->emu1010.wclock = emu_ci->vals[val]; |
988 | snd_emu1010_update_clock(emu); |
989 | |
990 | snd_emu1010_fpga_write(emu, EMU_HANA_UNMUTE, EMU_MUTE); |
991 | snd_emu1010_fpga_write(emu, EMU_HANA_WCLOCK, value: emu->emu1010.wclock); |
992 | spin_unlock_irq(lock: &emu->reg_lock); |
993 | |
994 | msleep(msecs: 10); // Allow DLL to settle |
995 | snd_emu1010_fpga_write(emu, EMU_HANA_UNMUTE, EMU_UNMUTE); |
996 | } else { |
997 | spin_unlock_irq(lock: &emu->reg_lock); |
998 | } |
999 | return change; |
1000 | } |
1001 | |
1002 | static const struct snd_kcontrol_new snd_emu1010_clock_source = |
1003 | { |
1004 | .access = SNDRV_CTL_ELEM_ACCESS_READWRITE, |
1005 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, |
1006 | .name = "Clock Source" , |
1007 | .count = 1, |
1008 | .info = snd_emu1010_clock_source_info, |
1009 | .get = snd_emu1010_clock_source_get, |
1010 | .put = snd_emu1010_clock_source_put |
1011 | }; |
1012 | |
1013 | static int snd_emu1010_clock_fallback_info(struct snd_kcontrol *kcontrol, |
1014 | struct snd_ctl_elem_info *uinfo) |
1015 | { |
1016 | static const char * const texts[2] = { |
1017 | "44100" , "48000" |
1018 | }; |
1019 | |
1020 | return snd_ctl_enum_info(info: uinfo, channels: 1, items: 2, names: texts); |
1021 | } |
1022 | |
1023 | static int snd_emu1010_clock_fallback_get(struct snd_kcontrol *kcontrol, |
1024 | struct snd_ctl_elem_value *ucontrol) |
1025 | { |
1026 | struct snd_emu10k1 *emu = snd_kcontrol_chip(kcontrol); |
1027 | |
1028 | ucontrol->value.enumerated.item[0] = emu->emu1010.clock_fallback; |
1029 | return 0; |
1030 | } |
1031 | |
1032 | static int snd_emu1010_clock_fallback_put(struct snd_kcontrol *kcontrol, |
1033 | struct snd_ctl_elem_value *ucontrol) |
1034 | { |
1035 | struct snd_emu10k1 *emu = snd_kcontrol_chip(kcontrol); |
1036 | unsigned int val = ucontrol->value.enumerated.item[0]; |
1037 | int change; |
1038 | |
1039 | if (val >= 2) |
1040 | return -EINVAL; |
1041 | change = (emu->emu1010.clock_fallback != val); |
1042 | if (change) { |
1043 | emu->emu1010.clock_fallback = val; |
1044 | snd_emu1010_fpga_write(emu, EMU_HANA_DEFCLOCK, value: 1 - val); |
1045 | } |
1046 | return change; |
1047 | } |
1048 | |
1049 | static const struct snd_kcontrol_new snd_emu1010_clock_fallback = |
1050 | { |
1051 | .access = SNDRV_CTL_ELEM_ACCESS_READWRITE, |
1052 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, |
1053 | .name = "Clock Fallback" , |
1054 | .count = 1, |
1055 | .info = snd_emu1010_clock_fallback_info, |
1056 | .get = snd_emu1010_clock_fallback_get, |
1057 | .put = snd_emu1010_clock_fallback_put |
1058 | }; |
1059 | |
1060 | static int snd_emu1010_optical_out_info(struct snd_kcontrol *kcontrol, |
1061 | struct snd_ctl_elem_info *uinfo) |
1062 | { |
1063 | static const char * const texts[2] = { |
1064 | "SPDIF" , "ADAT" |
1065 | }; |
1066 | |
1067 | return snd_ctl_enum_info(info: uinfo, channels: 1, items: 2, names: texts); |
1068 | } |
1069 | |
1070 | static int snd_emu1010_optical_out_get(struct snd_kcontrol *kcontrol, |
1071 | struct snd_ctl_elem_value *ucontrol) |
1072 | { |
1073 | struct snd_emu10k1 *emu = snd_kcontrol_chip(kcontrol); |
1074 | |
1075 | ucontrol->value.enumerated.item[0] = emu->emu1010.optical_out; |
1076 | return 0; |
1077 | } |
1078 | |
1079 | static int snd_emu1010_optical_out_put(struct snd_kcontrol *kcontrol, |
1080 | struct snd_ctl_elem_value *ucontrol) |
1081 | { |
1082 | struct snd_emu10k1 *emu = snd_kcontrol_chip(kcontrol); |
1083 | unsigned int val; |
1084 | u32 tmp; |
1085 | int change = 0; |
1086 | |
1087 | val = ucontrol->value.enumerated.item[0]; |
1088 | /* Limit: uinfo->value.enumerated.items = 2; */ |
1089 | if (val >= 2) |
1090 | return -EINVAL; |
1091 | change = (emu->emu1010.optical_out != val); |
1092 | if (change) { |
1093 | emu->emu1010.optical_out = val; |
1094 | tmp = (emu->emu1010.optical_in ? EMU_HANA_OPTICAL_IN_ADAT : EMU_HANA_OPTICAL_IN_SPDIF) | |
1095 | (emu->emu1010.optical_out ? EMU_HANA_OPTICAL_OUT_ADAT : EMU_HANA_OPTICAL_OUT_SPDIF); |
1096 | snd_emu1010_fpga_write(emu, EMU_HANA_OPTICAL_TYPE, value: tmp); |
1097 | } |
1098 | return change; |
1099 | } |
1100 | |
1101 | static const struct snd_kcontrol_new snd_emu1010_optical_out = { |
1102 | .access = SNDRV_CTL_ELEM_ACCESS_READWRITE, |
1103 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, |
1104 | .name = "Optical Output Mode" , |
1105 | .count = 1, |
1106 | .info = snd_emu1010_optical_out_info, |
1107 | .get = snd_emu1010_optical_out_get, |
1108 | .put = snd_emu1010_optical_out_put |
1109 | }; |
1110 | |
1111 | static int snd_emu1010_optical_in_info(struct snd_kcontrol *kcontrol, |
1112 | struct snd_ctl_elem_info *uinfo) |
1113 | { |
1114 | static const char * const texts[2] = { |
1115 | "SPDIF" , "ADAT" |
1116 | }; |
1117 | |
1118 | return snd_ctl_enum_info(info: uinfo, channels: 1, items: 2, names: texts); |
1119 | } |
1120 | |
1121 | static int snd_emu1010_optical_in_get(struct snd_kcontrol *kcontrol, |
1122 | struct snd_ctl_elem_value *ucontrol) |
1123 | { |
1124 | struct snd_emu10k1 *emu = snd_kcontrol_chip(kcontrol); |
1125 | |
1126 | ucontrol->value.enumerated.item[0] = emu->emu1010.optical_in; |
1127 | return 0; |
1128 | } |
1129 | |
1130 | static int snd_emu1010_optical_in_put(struct snd_kcontrol *kcontrol, |
1131 | struct snd_ctl_elem_value *ucontrol) |
1132 | { |
1133 | struct snd_emu10k1 *emu = snd_kcontrol_chip(kcontrol); |
1134 | unsigned int val; |
1135 | u32 tmp; |
1136 | int change = 0; |
1137 | |
1138 | val = ucontrol->value.enumerated.item[0]; |
1139 | /* Limit: uinfo->value.enumerated.items = 2; */ |
1140 | if (val >= 2) |
1141 | return -EINVAL; |
1142 | change = (emu->emu1010.optical_in != val); |
1143 | if (change) { |
1144 | emu->emu1010.optical_in = val; |
1145 | tmp = (emu->emu1010.optical_in ? EMU_HANA_OPTICAL_IN_ADAT : EMU_HANA_OPTICAL_IN_SPDIF) | |
1146 | (emu->emu1010.optical_out ? EMU_HANA_OPTICAL_OUT_ADAT : EMU_HANA_OPTICAL_OUT_SPDIF); |
1147 | snd_emu1010_fpga_write(emu, EMU_HANA_OPTICAL_TYPE, value: tmp); |
1148 | } |
1149 | return change; |
1150 | } |
1151 | |
1152 | static const struct snd_kcontrol_new snd_emu1010_optical_in = { |
1153 | .access = SNDRV_CTL_ELEM_ACCESS_READWRITE, |
1154 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, |
1155 | .name = "Optical Input Mode" , |
1156 | .count = 1, |
1157 | .info = snd_emu1010_optical_in_info, |
1158 | .get = snd_emu1010_optical_in_get, |
1159 | .put = snd_emu1010_optical_in_put |
1160 | }; |
1161 | |
1162 | static int snd_audigy_i2c_capture_source_info(struct snd_kcontrol *kcontrol, |
1163 | struct snd_ctl_elem_info *uinfo) |
1164 | { |
1165 | #if 0 |
1166 | static const char * const texts[4] = { |
1167 | "Unknown1" , "Unknown2" , "Mic" , "Line" |
1168 | }; |
1169 | #endif |
1170 | static const char * const texts[2] = { |
1171 | "Mic" , "Line" |
1172 | }; |
1173 | |
1174 | return snd_ctl_enum_info(info: uinfo, channels: 1, items: 2, names: texts); |
1175 | } |
1176 | |
1177 | static int snd_audigy_i2c_capture_source_get(struct snd_kcontrol *kcontrol, |
1178 | struct snd_ctl_elem_value *ucontrol) |
1179 | { |
1180 | struct snd_emu10k1 *emu = snd_kcontrol_chip(kcontrol); |
1181 | |
1182 | ucontrol->value.enumerated.item[0] = emu->i2c_capture_source; |
1183 | return 0; |
1184 | } |
1185 | |
1186 | static int snd_audigy_i2c_capture_source_put(struct snd_kcontrol *kcontrol, |
1187 | struct snd_ctl_elem_value *ucontrol) |
1188 | { |
1189 | struct snd_emu10k1 *emu = snd_kcontrol_chip(kcontrol); |
1190 | unsigned int source_id; |
1191 | unsigned int ngain, ogain; |
1192 | u16 gpio; |
1193 | int change = 0; |
1194 | u32 source; |
1195 | /* If the capture source has changed, |
1196 | * update the capture volume from the cached value |
1197 | * for the particular source. |
1198 | */ |
1199 | source_id = ucontrol->value.enumerated.item[0]; |
1200 | /* Limit: uinfo->value.enumerated.items = 2; */ |
1201 | /* emu->i2c_capture_volume */ |
1202 | if (source_id >= 2) |
1203 | return -EINVAL; |
1204 | change = (emu->i2c_capture_source != source_id); |
1205 | if (change) { |
1206 | snd_emu10k1_i2c_write(emu, ADC_MUX, value: 0); /* Mute input */ |
1207 | spin_lock_irq(lock: &emu->emu_lock); |
1208 | gpio = inw(port: emu->port + A_IOCFG); |
1209 | if (source_id==0) |
1210 | outw(value: gpio | 0x4, port: emu->port + A_IOCFG); |
1211 | else |
1212 | outw(value: gpio & ~0x4, port: emu->port + A_IOCFG); |
1213 | spin_unlock_irq(lock: &emu->emu_lock); |
1214 | |
1215 | ngain = emu->i2c_capture_volume[source_id][0]; /* Left */ |
1216 | ogain = emu->i2c_capture_volume[emu->i2c_capture_source][0]; /* Left */ |
1217 | if (ngain != ogain) |
1218 | snd_emu10k1_i2c_write(emu, ADC_ATTEN_ADCL, value: ((ngain) & 0xff)); |
1219 | ngain = emu->i2c_capture_volume[source_id][1]; /* Right */ |
1220 | ogain = emu->i2c_capture_volume[emu->i2c_capture_source][1]; /* Right */ |
1221 | if (ngain != ogain) |
1222 | snd_emu10k1_i2c_write(emu, ADC_ATTEN_ADCR, value: ((ngain) & 0xff)); |
1223 | |
1224 | source = 1 << (source_id + 2); |
1225 | snd_emu10k1_i2c_write(emu, ADC_MUX, value: source); /* Set source */ |
1226 | emu->i2c_capture_source = source_id; |
1227 | } |
1228 | return change; |
1229 | } |
1230 | |
1231 | static const struct snd_kcontrol_new snd_audigy_i2c_capture_source = |
1232 | { |
1233 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, |
1234 | .name = "Capture Source" , |
1235 | .info = snd_audigy_i2c_capture_source_info, |
1236 | .get = snd_audigy_i2c_capture_source_get, |
1237 | .put = snd_audigy_i2c_capture_source_put |
1238 | }; |
1239 | |
1240 | static int snd_audigy_i2c_volume_info(struct snd_kcontrol *kcontrol, |
1241 | struct snd_ctl_elem_info *uinfo) |
1242 | { |
1243 | uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER; |
1244 | uinfo->count = 2; |
1245 | uinfo->value.integer.min = 0; |
1246 | uinfo->value.integer.max = 255; |
1247 | return 0; |
1248 | } |
1249 | |
1250 | static int snd_audigy_i2c_volume_get(struct snd_kcontrol *kcontrol, |
1251 | struct snd_ctl_elem_value *ucontrol) |
1252 | { |
1253 | struct snd_emu10k1 *emu = snd_kcontrol_chip(kcontrol); |
1254 | unsigned int source_id; |
1255 | |
1256 | source_id = kcontrol->private_value; |
1257 | /* Limit: emu->i2c_capture_volume */ |
1258 | /* capture_source: uinfo->value.enumerated.items = 2 */ |
1259 | if (source_id >= 2) |
1260 | return -EINVAL; |
1261 | |
1262 | ucontrol->value.integer.value[0] = emu->i2c_capture_volume[source_id][0]; |
1263 | ucontrol->value.integer.value[1] = emu->i2c_capture_volume[source_id][1]; |
1264 | return 0; |
1265 | } |
1266 | |
1267 | static int snd_audigy_i2c_volume_put(struct snd_kcontrol *kcontrol, |
1268 | struct snd_ctl_elem_value *ucontrol) |
1269 | { |
1270 | struct snd_emu10k1 *emu = snd_kcontrol_chip(kcontrol); |
1271 | unsigned int ogain; |
1272 | unsigned int ngain0, ngain1; |
1273 | unsigned int source_id; |
1274 | int change = 0; |
1275 | |
1276 | source_id = kcontrol->private_value; |
1277 | /* Limit: emu->i2c_capture_volume */ |
1278 | /* capture_source: uinfo->value.enumerated.items = 2 */ |
1279 | if (source_id >= 2) |
1280 | return -EINVAL; |
1281 | ngain0 = ucontrol->value.integer.value[0]; |
1282 | ngain1 = ucontrol->value.integer.value[1]; |
1283 | if (ngain0 > 0xff) |
1284 | return -EINVAL; |
1285 | if (ngain1 > 0xff) |
1286 | return -EINVAL; |
1287 | ogain = emu->i2c_capture_volume[source_id][0]; /* Left */ |
1288 | if (ogain != ngain0) { |
1289 | if (emu->i2c_capture_source == source_id) |
1290 | snd_emu10k1_i2c_write(emu, ADC_ATTEN_ADCL, value: ngain0); |
1291 | emu->i2c_capture_volume[source_id][0] = ngain0; |
1292 | change = 1; |
1293 | } |
1294 | ogain = emu->i2c_capture_volume[source_id][1]; /* Right */ |
1295 | if (ogain != ngain1) { |
1296 | if (emu->i2c_capture_source == source_id) |
1297 | snd_emu10k1_i2c_write(emu, ADC_ATTEN_ADCR, value: ngain1); |
1298 | emu->i2c_capture_volume[source_id][1] = ngain1; |
1299 | change = 1; |
1300 | } |
1301 | |
1302 | return change; |
1303 | } |
1304 | |
1305 | static const struct snd_kcontrol_new i2c_volume_ctl = { |
1306 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, |
1307 | .access = SNDRV_CTL_ELEM_ACCESS_READWRITE | |
1308 | SNDRV_CTL_ELEM_ACCESS_TLV_READ, |
1309 | .info = snd_audigy_i2c_volume_info, |
1310 | .get = snd_audigy_i2c_volume_get, |
1311 | .put = snd_audigy_i2c_volume_put, |
1312 | .tlv = { .p = snd_audigy_db_scale2 } |
1313 | }; |
1314 | |
1315 | static const char * const snd_audigy_i2c_volume_ctls[] = { |
1316 | "Mic Capture Volume" , |
1317 | "Line Capture Volume" , |
1318 | }; |
1319 | |
1320 | #if 0 |
1321 | static int snd_audigy_spdif_output_rate_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo) |
1322 | { |
1323 | static const char * const texts[] = {"44100" , "48000" , "96000" }; |
1324 | |
1325 | return snd_ctl_enum_info(uinfo, 1, 3, texts); |
1326 | } |
1327 | |
1328 | static int snd_audigy_spdif_output_rate_get(struct snd_kcontrol *kcontrol, |
1329 | struct snd_ctl_elem_value *ucontrol) |
1330 | { |
1331 | struct snd_emu10k1 *emu = snd_kcontrol_chip(kcontrol); |
1332 | unsigned int tmp; |
1333 | |
1334 | tmp = snd_emu10k1_ptr_read(emu, A_SPDIF_SAMPLERATE, 0); |
1335 | switch (tmp & A_SPDIF_RATE_MASK) { |
1336 | case A_SPDIF_44100: |
1337 | ucontrol->value.enumerated.item[0] = 0; |
1338 | break; |
1339 | case A_SPDIF_48000: |
1340 | ucontrol->value.enumerated.item[0] = 1; |
1341 | break; |
1342 | case A_SPDIF_96000: |
1343 | ucontrol->value.enumerated.item[0] = 2; |
1344 | break; |
1345 | default: |
1346 | ucontrol->value.enumerated.item[0] = 1; |
1347 | } |
1348 | return 0; |
1349 | } |
1350 | |
1351 | static int snd_audigy_spdif_output_rate_put(struct snd_kcontrol *kcontrol, |
1352 | struct snd_ctl_elem_value *ucontrol) |
1353 | { |
1354 | struct snd_emu10k1 *emu = snd_kcontrol_chip(kcontrol); |
1355 | int change; |
1356 | unsigned int reg, val, tmp; |
1357 | |
1358 | switch(ucontrol->value.enumerated.item[0]) { |
1359 | case 0: |
1360 | val = A_SPDIF_44100; |
1361 | break; |
1362 | case 1: |
1363 | val = A_SPDIF_48000; |
1364 | break; |
1365 | case 2: |
1366 | val = A_SPDIF_96000; |
1367 | break; |
1368 | default: |
1369 | val = A_SPDIF_48000; |
1370 | break; |
1371 | } |
1372 | |
1373 | |
1374 | spin_lock_irq(&emu->reg_lock); |
1375 | reg = snd_emu10k1_ptr_read(emu, A_SPDIF_SAMPLERATE, 0); |
1376 | tmp = reg & ~A_SPDIF_RATE_MASK; |
1377 | tmp |= val; |
1378 | change = (tmp != reg); |
1379 | if (change) |
1380 | snd_emu10k1_ptr_write(emu, A_SPDIF_SAMPLERATE, 0, tmp); |
1381 | spin_unlock_irq(&emu->reg_lock); |
1382 | return change; |
1383 | } |
1384 | |
1385 | static const struct snd_kcontrol_new snd_audigy_spdif_output_rate = |
1386 | { |
1387 | .access = SNDRV_CTL_ELEM_ACCESS_READWRITE, |
1388 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, |
1389 | .name = "Audigy SPDIF Output Sample Rate" , |
1390 | .count = 1, |
1391 | .info = snd_audigy_spdif_output_rate_info, |
1392 | .get = snd_audigy_spdif_output_rate_get, |
1393 | .put = snd_audigy_spdif_output_rate_put |
1394 | }; |
1395 | #endif |
1396 | |
1397 | static int snd_emu10k1_spdif_put(struct snd_kcontrol *kcontrol, |
1398 | struct snd_ctl_elem_value *ucontrol) |
1399 | { |
1400 | struct snd_emu10k1 *emu = snd_kcontrol_chip(kcontrol); |
1401 | unsigned int idx = snd_ctl_get_ioffidx(kctl: kcontrol, id: &ucontrol->id); |
1402 | int change; |
1403 | unsigned int val; |
1404 | |
1405 | /* Limit: emu->spdif_bits */ |
1406 | if (idx >= 3) |
1407 | return -EINVAL; |
1408 | val = (ucontrol->value.iec958.status[0] << 0) | |
1409 | (ucontrol->value.iec958.status[1] << 8) | |
1410 | (ucontrol->value.iec958.status[2] << 16) | |
1411 | (ucontrol->value.iec958.status[3] << 24); |
1412 | change = val != emu->spdif_bits[idx]; |
1413 | if (change) { |
1414 | snd_emu10k1_ptr_write(emu, SPCS0 + idx, chn: 0, data: val); |
1415 | emu->spdif_bits[idx] = val; |
1416 | } |
1417 | return change; |
1418 | } |
1419 | |
1420 | static const struct snd_kcontrol_new snd_emu10k1_spdif_mask_control = |
1421 | { |
1422 | .access = SNDRV_CTL_ELEM_ACCESS_READ, |
1423 | .iface = SNDRV_CTL_ELEM_IFACE_PCM, |
1424 | .name = SNDRV_CTL_NAME_IEC958("" ,PLAYBACK,MASK), |
1425 | .count = 3, |
1426 | .info = snd_emu10k1_spdif_info, |
1427 | .get = snd_emu10k1_spdif_get_mask |
1428 | }; |
1429 | |
1430 | static const struct snd_kcontrol_new snd_emu10k1_spdif_control = |
1431 | { |
1432 | .iface = SNDRV_CTL_ELEM_IFACE_PCM, |
1433 | .name = SNDRV_CTL_NAME_IEC958("" ,PLAYBACK,DEFAULT), |
1434 | .count = 3, |
1435 | .info = snd_emu10k1_spdif_info, |
1436 | .get = snd_emu10k1_spdif_get, |
1437 | .put = snd_emu10k1_spdif_put |
1438 | }; |
1439 | |
1440 | |
1441 | static void update_emu10k1_fxrt(struct snd_emu10k1 *emu, int voice, unsigned char *route) |
1442 | { |
1443 | if (emu->audigy) { |
1444 | snd_emu10k1_ptr_write_multiple(emu, chn: voice, |
1445 | A_FXRT1, snd_emu10k1_compose_audigy_fxrt1(route), |
1446 | A_FXRT2, snd_emu10k1_compose_audigy_fxrt2(route), |
1447 | REGLIST_END); |
1448 | } else { |
1449 | snd_emu10k1_ptr_write(emu, FXRT, chn: voice, |
1450 | snd_emu10k1_compose_send_routing(route)); |
1451 | } |
1452 | } |
1453 | |
1454 | static void update_emu10k1_send_volume(struct snd_emu10k1 *emu, int voice, unsigned char *volume) |
1455 | { |
1456 | snd_emu10k1_ptr_write(emu, reg: PTRX_FXSENDAMOUNT_A, chn: voice, data: volume[0]); |
1457 | snd_emu10k1_ptr_write(emu, reg: PTRX_FXSENDAMOUNT_B, chn: voice, data: volume[1]); |
1458 | snd_emu10k1_ptr_write(emu, reg: PSST_FXSENDAMOUNT_C, chn: voice, data: volume[2]); |
1459 | snd_emu10k1_ptr_write(emu, reg: DSL_FXSENDAMOUNT_D, chn: voice, data: volume[3]); |
1460 | if (emu->audigy) { |
1461 | snd_emu10k1_ptr_write(emu, A_SENDAMOUNTS, chn: voice, |
1462 | snd_emu10k1_compose_audigy_sendamounts(volume)); |
1463 | } |
1464 | } |
1465 | |
1466 | /* PCM stream controls */ |
1467 | |
1468 | static int snd_emu10k1_send_routing_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo) |
1469 | { |
1470 | struct snd_emu10k1 *emu = snd_kcontrol_chip(kcontrol); |
1471 | uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER; |
1472 | uinfo->count = emu->audigy ? 3*8 : 3*4; |
1473 | uinfo->value.integer.min = 0; |
1474 | uinfo->value.integer.max = emu->audigy ? 0x3f : 0x0f; |
1475 | return 0; |
1476 | } |
1477 | |
1478 | static int snd_emu10k1_send_routing_get(struct snd_kcontrol *kcontrol, |
1479 | struct snd_ctl_elem_value *ucontrol) |
1480 | { |
1481 | struct snd_emu10k1 *emu = snd_kcontrol_chip(kcontrol); |
1482 | struct snd_emu10k1_pcm_mixer *mix = |
1483 | &emu->pcm_mixer[snd_ctl_get_ioffidx(kctl: kcontrol, id: &ucontrol->id)]; |
1484 | int voice, idx; |
1485 | int num_efx = emu->audigy ? 8 : 4; |
1486 | int mask = emu->audigy ? 0x3f : 0x0f; |
1487 | |
1488 | for (voice = 0; voice < 3; voice++) |
1489 | for (idx = 0; idx < num_efx; idx++) |
1490 | ucontrol->value.integer.value[(voice * num_efx) + idx] = |
1491 | mix->send_routing[voice][idx] & mask; |
1492 | return 0; |
1493 | } |
1494 | |
1495 | static int snd_emu10k1_send_routing_put(struct snd_kcontrol *kcontrol, |
1496 | struct snd_ctl_elem_value *ucontrol) |
1497 | { |
1498 | struct snd_emu10k1 *emu = snd_kcontrol_chip(kcontrol); |
1499 | struct snd_emu10k1_pcm_mixer *mix = |
1500 | &emu->pcm_mixer[snd_ctl_get_ioffidx(kctl: kcontrol, id: &ucontrol->id)]; |
1501 | int change = 0, voice, idx, val; |
1502 | int num_efx = emu->audigy ? 8 : 4; |
1503 | int mask = emu->audigy ? 0x3f : 0x0f; |
1504 | |
1505 | spin_lock_irq(lock: &emu->reg_lock); |
1506 | for (voice = 0; voice < 3; voice++) |
1507 | for (idx = 0; idx < num_efx; idx++) { |
1508 | val = ucontrol->value.integer.value[(voice * num_efx) + idx] & mask; |
1509 | if (mix->send_routing[voice][idx] != val) { |
1510 | mix->send_routing[voice][idx] = val; |
1511 | change = 1; |
1512 | } |
1513 | } |
1514 | if (change && mix->epcm && mix->epcm->voices[0]) { |
1515 | if (!mix->epcm->voices[0]->last) { |
1516 | update_emu10k1_fxrt(emu, voice: mix->epcm->voices[0]->number, |
1517 | route: &mix->send_routing[1][0]); |
1518 | update_emu10k1_fxrt(emu, voice: mix->epcm->voices[0]->number + 1, |
1519 | route: &mix->send_routing[2][0]); |
1520 | } else { |
1521 | update_emu10k1_fxrt(emu, voice: mix->epcm->voices[0]->number, |
1522 | route: &mix->send_routing[0][0]); |
1523 | } |
1524 | } |
1525 | spin_unlock_irq(lock: &emu->reg_lock); |
1526 | return change; |
1527 | } |
1528 | |
1529 | static const struct snd_kcontrol_new snd_emu10k1_send_routing_control = |
1530 | { |
1531 | .access = SNDRV_CTL_ELEM_ACCESS_READWRITE | SNDRV_CTL_ELEM_ACCESS_INACTIVE, |
1532 | .iface = SNDRV_CTL_ELEM_IFACE_PCM, |
1533 | .name = "EMU10K1 PCM Send Routing" , |
1534 | .count = 32, |
1535 | .info = snd_emu10k1_send_routing_info, |
1536 | .get = snd_emu10k1_send_routing_get, |
1537 | .put = snd_emu10k1_send_routing_put |
1538 | }; |
1539 | |
1540 | static int snd_emu10k1_send_volume_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo) |
1541 | { |
1542 | struct snd_emu10k1 *emu = snd_kcontrol_chip(kcontrol); |
1543 | uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER; |
1544 | uinfo->count = emu->audigy ? 3*8 : 3*4; |
1545 | uinfo->value.integer.min = 0; |
1546 | uinfo->value.integer.max = 255; |
1547 | return 0; |
1548 | } |
1549 | |
1550 | static int snd_emu10k1_send_volume_get(struct snd_kcontrol *kcontrol, |
1551 | struct snd_ctl_elem_value *ucontrol) |
1552 | { |
1553 | struct snd_emu10k1 *emu = snd_kcontrol_chip(kcontrol); |
1554 | struct snd_emu10k1_pcm_mixer *mix = |
1555 | &emu->pcm_mixer[snd_ctl_get_ioffidx(kctl: kcontrol, id: &ucontrol->id)]; |
1556 | int idx; |
1557 | int num_efx = emu->audigy ? 8 : 4; |
1558 | |
1559 | for (idx = 0; idx < 3*num_efx; idx++) |
1560 | ucontrol->value.integer.value[idx] = mix->send_volume[idx/num_efx][idx%num_efx]; |
1561 | return 0; |
1562 | } |
1563 | |
1564 | static int snd_emu10k1_send_volume_put(struct snd_kcontrol *kcontrol, |
1565 | struct snd_ctl_elem_value *ucontrol) |
1566 | { |
1567 | struct snd_emu10k1 *emu = snd_kcontrol_chip(kcontrol); |
1568 | struct snd_emu10k1_pcm_mixer *mix = |
1569 | &emu->pcm_mixer[snd_ctl_get_ioffidx(kctl: kcontrol, id: &ucontrol->id)]; |
1570 | int change = 0, idx, val; |
1571 | int num_efx = emu->audigy ? 8 : 4; |
1572 | |
1573 | spin_lock_irq(lock: &emu->reg_lock); |
1574 | for (idx = 0; idx < 3*num_efx; idx++) { |
1575 | val = ucontrol->value.integer.value[idx] & 255; |
1576 | if (mix->send_volume[idx/num_efx][idx%num_efx] != val) { |
1577 | mix->send_volume[idx/num_efx][idx%num_efx] = val; |
1578 | change = 1; |
1579 | } |
1580 | } |
1581 | if (change && mix->epcm && mix->epcm->voices[0]) { |
1582 | if (!mix->epcm->voices[0]->last) { |
1583 | update_emu10k1_send_volume(emu, voice: mix->epcm->voices[0]->number, |
1584 | volume: &mix->send_volume[1][0]); |
1585 | update_emu10k1_send_volume(emu, voice: mix->epcm->voices[0]->number + 1, |
1586 | volume: &mix->send_volume[2][0]); |
1587 | } else { |
1588 | update_emu10k1_send_volume(emu, voice: mix->epcm->voices[0]->number, |
1589 | volume: &mix->send_volume[0][0]); |
1590 | } |
1591 | } |
1592 | spin_unlock_irq(lock: &emu->reg_lock); |
1593 | return change; |
1594 | } |
1595 | |
1596 | static const struct snd_kcontrol_new snd_emu10k1_send_volume_control = |
1597 | { |
1598 | .access = SNDRV_CTL_ELEM_ACCESS_READWRITE | SNDRV_CTL_ELEM_ACCESS_INACTIVE, |
1599 | .iface = SNDRV_CTL_ELEM_IFACE_PCM, |
1600 | .name = "EMU10K1 PCM Send Volume" , |
1601 | .count = 32, |
1602 | .info = snd_emu10k1_send_volume_info, |
1603 | .get = snd_emu10k1_send_volume_get, |
1604 | .put = snd_emu10k1_send_volume_put |
1605 | }; |
1606 | |
1607 | static int snd_emu10k1_attn_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo) |
1608 | { |
1609 | uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER; |
1610 | uinfo->count = 3; |
1611 | uinfo->value.integer.min = 0; |
1612 | uinfo->value.integer.max = 0x1fffd; |
1613 | return 0; |
1614 | } |
1615 | |
1616 | static int snd_emu10k1_attn_get(struct snd_kcontrol *kcontrol, |
1617 | struct snd_ctl_elem_value *ucontrol) |
1618 | { |
1619 | struct snd_emu10k1 *emu = snd_kcontrol_chip(kcontrol); |
1620 | struct snd_emu10k1_pcm_mixer *mix = |
1621 | &emu->pcm_mixer[snd_ctl_get_ioffidx(kctl: kcontrol, id: &ucontrol->id)]; |
1622 | int idx; |
1623 | |
1624 | for (idx = 0; idx < 3; idx++) |
1625 | ucontrol->value.integer.value[idx] = mix->attn[idx] * 0xffffU / 0x8000U; |
1626 | return 0; |
1627 | } |
1628 | |
1629 | static int snd_emu10k1_attn_put(struct snd_kcontrol *kcontrol, |
1630 | struct snd_ctl_elem_value *ucontrol) |
1631 | { |
1632 | struct snd_emu10k1 *emu = snd_kcontrol_chip(kcontrol); |
1633 | struct snd_emu10k1_pcm_mixer *mix = |
1634 | &emu->pcm_mixer[snd_ctl_get_ioffidx(kctl: kcontrol, id: &ucontrol->id)]; |
1635 | int change = 0, idx, val; |
1636 | |
1637 | spin_lock_irq(lock: &emu->reg_lock); |
1638 | for (idx = 0; idx < 3; idx++) { |
1639 | unsigned uval = ucontrol->value.integer.value[idx] & 0x1ffff; |
1640 | val = uval * 0x8000U / 0xffffU; |
1641 | if (mix->attn[idx] != val) { |
1642 | mix->attn[idx] = val; |
1643 | change = 1; |
1644 | } |
1645 | } |
1646 | if (change && mix->epcm && mix->epcm->voices[0]) { |
1647 | if (!mix->epcm->voices[0]->last) { |
1648 | snd_emu10k1_ptr_write(emu, reg: VTFT_VOLUMETARGET, chn: mix->epcm->voices[0]->number, data: mix->attn[1]); |
1649 | snd_emu10k1_ptr_write(emu, reg: VTFT_VOLUMETARGET, chn: mix->epcm->voices[0]->number + 1, data: mix->attn[2]); |
1650 | } else { |
1651 | snd_emu10k1_ptr_write(emu, reg: VTFT_VOLUMETARGET, chn: mix->epcm->voices[0]->number, data: mix->attn[0]); |
1652 | } |
1653 | } |
1654 | spin_unlock_irq(lock: &emu->reg_lock); |
1655 | return change; |
1656 | } |
1657 | |
1658 | static const struct snd_kcontrol_new snd_emu10k1_attn_control = |
1659 | { |
1660 | .access = SNDRV_CTL_ELEM_ACCESS_READWRITE | SNDRV_CTL_ELEM_ACCESS_INACTIVE, |
1661 | .iface = SNDRV_CTL_ELEM_IFACE_PCM, |
1662 | .name = "EMU10K1 PCM Volume" , |
1663 | .count = 32, |
1664 | .info = snd_emu10k1_attn_info, |
1665 | .get = snd_emu10k1_attn_get, |
1666 | .put = snd_emu10k1_attn_put |
1667 | }; |
1668 | |
1669 | /* Mutichannel PCM stream controls */ |
1670 | |
1671 | static int snd_emu10k1_efx_send_routing_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo) |
1672 | { |
1673 | struct snd_emu10k1 *emu = snd_kcontrol_chip(kcontrol); |
1674 | uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER; |
1675 | uinfo->count = emu->audigy ? 8 : 4; |
1676 | uinfo->value.integer.min = 0; |
1677 | uinfo->value.integer.max = emu->audigy ? 0x3f : 0x0f; |
1678 | return 0; |
1679 | } |
1680 | |
1681 | static int snd_emu10k1_efx_send_routing_get(struct snd_kcontrol *kcontrol, |
1682 | struct snd_ctl_elem_value *ucontrol) |
1683 | { |
1684 | struct snd_emu10k1 *emu = snd_kcontrol_chip(kcontrol); |
1685 | struct snd_emu10k1_pcm_mixer *mix = |
1686 | &emu->efx_pcm_mixer[snd_ctl_get_ioffidx(kctl: kcontrol, id: &ucontrol->id)]; |
1687 | int idx; |
1688 | int num_efx = emu->audigy ? 8 : 4; |
1689 | int mask = emu->audigy ? 0x3f : 0x0f; |
1690 | |
1691 | for (idx = 0; idx < num_efx; idx++) |
1692 | ucontrol->value.integer.value[idx] = |
1693 | mix->send_routing[0][idx] & mask; |
1694 | return 0; |
1695 | } |
1696 | |
1697 | static int snd_emu10k1_efx_send_routing_put(struct snd_kcontrol *kcontrol, |
1698 | struct snd_ctl_elem_value *ucontrol) |
1699 | { |
1700 | struct snd_emu10k1 *emu = snd_kcontrol_chip(kcontrol); |
1701 | int ch = snd_ctl_get_ioffidx(kctl: kcontrol, id: &ucontrol->id); |
1702 | struct snd_emu10k1_pcm_mixer *mix = &emu->efx_pcm_mixer[ch]; |
1703 | int change = 0, idx, val; |
1704 | int num_efx = emu->audigy ? 8 : 4; |
1705 | int mask = emu->audigy ? 0x3f : 0x0f; |
1706 | |
1707 | spin_lock_irq(lock: &emu->reg_lock); |
1708 | for (idx = 0; idx < num_efx; idx++) { |
1709 | val = ucontrol->value.integer.value[idx] & mask; |
1710 | if (mix->send_routing[0][idx] != val) { |
1711 | mix->send_routing[0][idx] = val; |
1712 | change = 1; |
1713 | } |
1714 | } |
1715 | |
1716 | if (change && mix->epcm) { |
1717 | if (mix->epcm->voices[ch]) { |
1718 | update_emu10k1_fxrt(emu, voice: mix->epcm->voices[ch]->number, |
1719 | route: &mix->send_routing[0][0]); |
1720 | } |
1721 | } |
1722 | spin_unlock_irq(lock: &emu->reg_lock); |
1723 | return change; |
1724 | } |
1725 | |
1726 | static const struct snd_kcontrol_new snd_emu10k1_efx_send_routing_control = |
1727 | { |
1728 | .access = SNDRV_CTL_ELEM_ACCESS_READWRITE | SNDRV_CTL_ELEM_ACCESS_INACTIVE, |
1729 | .iface = SNDRV_CTL_ELEM_IFACE_PCM, |
1730 | .name = "Multichannel PCM Send Routing" , |
1731 | .count = 16, |
1732 | .info = snd_emu10k1_efx_send_routing_info, |
1733 | .get = snd_emu10k1_efx_send_routing_get, |
1734 | .put = snd_emu10k1_efx_send_routing_put |
1735 | }; |
1736 | |
1737 | static int snd_emu10k1_efx_send_volume_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo) |
1738 | { |
1739 | struct snd_emu10k1 *emu = snd_kcontrol_chip(kcontrol); |
1740 | uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER; |
1741 | uinfo->count = emu->audigy ? 8 : 4; |
1742 | uinfo->value.integer.min = 0; |
1743 | uinfo->value.integer.max = 255; |
1744 | return 0; |
1745 | } |
1746 | |
1747 | static int snd_emu10k1_efx_send_volume_get(struct snd_kcontrol *kcontrol, |
1748 | struct snd_ctl_elem_value *ucontrol) |
1749 | { |
1750 | struct snd_emu10k1 *emu = snd_kcontrol_chip(kcontrol); |
1751 | struct snd_emu10k1_pcm_mixer *mix = |
1752 | &emu->efx_pcm_mixer[snd_ctl_get_ioffidx(kctl: kcontrol, id: &ucontrol->id)]; |
1753 | int idx; |
1754 | int num_efx = emu->audigy ? 8 : 4; |
1755 | |
1756 | for (idx = 0; idx < num_efx; idx++) |
1757 | ucontrol->value.integer.value[idx] = mix->send_volume[0][idx]; |
1758 | return 0; |
1759 | } |
1760 | |
1761 | static int snd_emu10k1_efx_send_volume_put(struct snd_kcontrol *kcontrol, |
1762 | struct snd_ctl_elem_value *ucontrol) |
1763 | { |
1764 | struct snd_emu10k1 *emu = snd_kcontrol_chip(kcontrol); |
1765 | int ch = snd_ctl_get_ioffidx(kctl: kcontrol, id: &ucontrol->id); |
1766 | struct snd_emu10k1_pcm_mixer *mix = &emu->efx_pcm_mixer[ch]; |
1767 | int change = 0, idx, val; |
1768 | int num_efx = emu->audigy ? 8 : 4; |
1769 | |
1770 | spin_lock_irq(lock: &emu->reg_lock); |
1771 | for (idx = 0; idx < num_efx; idx++) { |
1772 | val = ucontrol->value.integer.value[idx] & 255; |
1773 | if (mix->send_volume[0][idx] != val) { |
1774 | mix->send_volume[0][idx] = val; |
1775 | change = 1; |
1776 | } |
1777 | } |
1778 | if (change && mix->epcm) { |
1779 | if (mix->epcm->voices[ch]) { |
1780 | update_emu10k1_send_volume(emu, voice: mix->epcm->voices[ch]->number, |
1781 | volume: &mix->send_volume[0][0]); |
1782 | } |
1783 | } |
1784 | spin_unlock_irq(lock: &emu->reg_lock); |
1785 | return change; |
1786 | } |
1787 | |
1788 | |
1789 | static const struct snd_kcontrol_new snd_emu10k1_efx_send_volume_control = |
1790 | { |
1791 | .access = SNDRV_CTL_ELEM_ACCESS_READWRITE | SNDRV_CTL_ELEM_ACCESS_INACTIVE, |
1792 | .iface = SNDRV_CTL_ELEM_IFACE_PCM, |
1793 | .name = "Multichannel PCM Send Volume" , |
1794 | .count = 16, |
1795 | .info = snd_emu10k1_efx_send_volume_info, |
1796 | .get = snd_emu10k1_efx_send_volume_get, |
1797 | .put = snd_emu10k1_efx_send_volume_put |
1798 | }; |
1799 | |
1800 | static int snd_emu10k1_efx_attn_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo) |
1801 | { |
1802 | uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER; |
1803 | uinfo->count = 1; |
1804 | uinfo->value.integer.min = 0; |
1805 | uinfo->value.integer.max = 0x1fffd; |
1806 | return 0; |
1807 | } |
1808 | |
1809 | static int snd_emu10k1_efx_attn_get(struct snd_kcontrol *kcontrol, |
1810 | struct snd_ctl_elem_value *ucontrol) |
1811 | { |
1812 | struct snd_emu10k1 *emu = snd_kcontrol_chip(kcontrol); |
1813 | struct snd_emu10k1_pcm_mixer *mix = |
1814 | &emu->efx_pcm_mixer[snd_ctl_get_ioffidx(kctl: kcontrol, id: &ucontrol->id)]; |
1815 | |
1816 | ucontrol->value.integer.value[0] = mix->attn[0] * 0xffffU / 0x8000U; |
1817 | return 0; |
1818 | } |
1819 | |
1820 | static int snd_emu10k1_efx_attn_put(struct snd_kcontrol *kcontrol, |
1821 | struct snd_ctl_elem_value *ucontrol) |
1822 | { |
1823 | struct snd_emu10k1 *emu = snd_kcontrol_chip(kcontrol); |
1824 | int ch = snd_ctl_get_ioffidx(kctl: kcontrol, id: &ucontrol->id); |
1825 | struct snd_emu10k1_pcm_mixer *mix = &emu->efx_pcm_mixer[ch]; |
1826 | int change = 0, val; |
1827 | unsigned uval; |
1828 | |
1829 | spin_lock_irq(lock: &emu->reg_lock); |
1830 | uval = ucontrol->value.integer.value[0] & 0x1ffff; |
1831 | val = uval * 0x8000U / 0xffffU; |
1832 | if (mix->attn[0] != val) { |
1833 | mix->attn[0] = val; |
1834 | change = 1; |
1835 | } |
1836 | if (change && mix->epcm) { |
1837 | if (mix->epcm->voices[ch]) { |
1838 | snd_emu10k1_ptr_write(emu, reg: VTFT_VOLUMETARGET, chn: mix->epcm->voices[ch]->number, data: mix->attn[0]); |
1839 | } |
1840 | } |
1841 | spin_unlock_irq(lock: &emu->reg_lock); |
1842 | return change; |
1843 | } |
1844 | |
1845 | static const struct snd_kcontrol_new snd_emu10k1_efx_attn_control = |
1846 | { |
1847 | .access = SNDRV_CTL_ELEM_ACCESS_READWRITE | SNDRV_CTL_ELEM_ACCESS_INACTIVE, |
1848 | .iface = SNDRV_CTL_ELEM_IFACE_PCM, |
1849 | .name = "Multichannel PCM Volume" , |
1850 | .count = 16, |
1851 | .info = snd_emu10k1_efx_attn_info, |
1852 | .get = snd_emu10k1_efx_attn_get, |
1853 | .put = snd_emu10k1_efx_attn_put |
1854 | }; |
1855 | |
1856 | #define snd_emu10k1_shared_spdif_info snd_ctl_boolean_mono_info |
1857 | |
1858 | static int snd_emu10k1_shared_spdif_get(struct snd_kcontrol *kcontrol, |
1859 | struct snd_ctl_elem_value *ucontrol) |
1860 | { |
1861 | struct snd_emu10k1 *emu = snd_kcontrol_chip(kcontrol); |
1862 | |
1863 | if (emu->audigy) |
1864 | ucontrol->value.integer.value[0] = inw(port: emu->port + A_IOCFG) & A_IOCFG_GPOUT0 ? 1 : 0; |
1865 | else |
1866 | ucontrol->value.integer.value[0] = inl(port: emu->port + HCFG) & HCFG_GPOUT0 ? 1 : 0; |
1867 | if (emu->card_capabilities->invert_shared_spdif) |
1868 | ucontrol->value.integer.value[0] = |
1869 | !ucontrol->value.integer.value[0]; |
1870 | |
1871 | return 0; |
1872 | } |
1873 | |
1874 | static int snd_emu10k1_shared_spdif_put(struct snd_kcontrol *kcontrol, |
1875 | struct snd_ctl_elem_value *ucontrol) |
1876 | { |
1877 | struct snd_emu10k1 *emu = snd_kcontrol_chip(kcontrol); |
1878 | unsigned int reg, val, sw; |
1879 | int change = 0; |
1880 | |
1881 | sw = ucontrol->value.integer.value[0]; |
1882 | if (emu->card_capabilities->invert_shared_spdif) |
1883 | sw = !sw; |
1884 | spin_lock_irq(lock: &emu->emu_lock); |
1885 | if ( emu->card_capabilities->i2c_adc) { |
1886 | /* Do nothing for Audigy 2 ZS Notebook */ |
1887 | } else if (emu->audigy) { |
1888 | reg = inw(port: emu->port + A_IOCFG); |
1889 | val = sw ? A_IOCFG_GPOUT0 : 0; |
1890 | change = (reg & A_IOCFG_GPOUT0) != val; |
1891 | if (change) { |
1892 | reg &= ~A_IOCFG_GPOUT0; |
1893 | reg |= val; |
1894 | outw(value: reg | val, port: emu->port + A_IOCFG); |
1895 | } |
1896 | } |
1897 | reg = inl(port: emu->port + HCFG); |
1898 | val = sw ? HCFG_GPOUT0 : 0; |
1899 | change |= (reg & HCFG_GPOUT0) != val; |
1900 | if (change) { |
1901 | reg &= ~HCFG_GPOUT0; |
1902 | reg |= val; |
1903 | outl(value: reg | val, port: emu->port + HCFG); |
1904 | } |
1905 | spin_unlock_irq(lock: &emu->emu_lock); |
1906 | return change; |
1907 | } |
1908 | |
1909 | static const struct snd_kcontrol_new snd_emu10k1_shared_spdif = |
1910 | { |
1911 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, |
1912 | .name = "SB Live Analog/Digital Output Jack" , |
1913 | .info = snd_emu10k1_shared_spdif_info, |
1914 | .get = snd_emu10k1_shared_spdif_get, |
1915 | .put = snd_emu10k1_shared_spdif_put |
1916 | }; |
1917 | |
1918 | static const struct snd_kcontrol_new snd_audigy_shared_spdif = |
1919 | { |
1920 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, |
1921 | .name = "Audigy Analog/Digital Output Jack" , |
1922 | .info = snd_emu10k1_shared_spdif_info, |
1923 | .get = snd_emu10k1_shared_spdif_get, |
1924 | .put = snd_emu10k1_shared_spdif_put |
1925 | }; |
1926 | |
1927 | /* workaround for too low volume on Audigy due to 16bit/24bit conversion */ |
1928 | |
1929 | #define snd_audigy_capture_boost_info snd_ctl_boolean_mono_info |
1930 | |
1931 | static int snd_audigy_capture_boost_get(struct snd_kcontrol *kcontrol, |
1932 | struct snd_ctl_elem_value *ucontrol) |
1933 | { |
1934 | struct snd_emu10k1 *emu = snd_kcontrol_chip(kcontrol); |
1935 | unsigned int val; |
1936 | |
1937 | /* FIXME: better to use a cached version */ |
1938 | val = snd_ac97_read(ac97: emu->ac97, AC97_REC_GAIN); |
1939 | ucontrol->value.integer.value[0] = !!val; |
1940 | return 0; |
1941 | } |
1942 | |
1943 | static int snd_audigy_capture_boost_put(struct snd_kcontrol *kcontrol, |
1944 | struct snd_ctl_elem_value *ucontrol) |
1945 | { |
1946 | struct snd_emu10k1 *emu = snd_kcontrol_chip(kcontrol); |
1947 | unsigned int val; |
1948 | |
1949 | if (ucontrol->value.integer.value[0]) |
1950 | val = 0x0f0f; |
1951 | else |
1952 | val = 0; |
1953 | return snd_ac97_update(ac97: emu->ac97, AC97_REC_GAIN, value: val); |
1954 | } |
1955 | |
1956 | static const struct snd_kcontrol_new snd_audigy_capture_boost = |
1957 | { |
1958 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, |
1959 | .name = "Mic Extra Boost" , |
1960 | .info = snd_audigy_capture_boost_info, |
1961 | .get = snd_audigy_capture_boost_get, |
1962 | .put = snd_audigy_capture_boost_put |
1963 | }; |
1964 | |
1965 | |
1966 | /* |
1967 | */ |
1968 | static void snd_emu10k1_mixer_free_ac97(struct snd_ac97 *ac97) |
1969 | { |
1970 | struct snd_emu10k1 *emu = ac97->private_data; |
1971 | emu->ac97 = NULL; |
1972 | } |
1973 | |
1974 | /* |
1975 | */ |
1976 | static int remove_ctl(struct snd_card *card, const char *name) |
1977 | { |
1978 | struct snd_ctl_elem_id id; |
1979 | memset(&id, 0, sizeof(id)); |
1980 | strcpy(p: id.name, q: name); |
1981 | id.iface = SNDRV_CTL_ELEM_IFACE_MIXER; |
1982 | return snd_ctl_remove_id(card, id: &id); |
1983 | } |
1984 | |
1985 | static int rename_ctl(struct snd_card *card, const char *src, const char *dst) |
1986 | { |
1987 | struct snd_kcontrol *kctl = snd_ctl_find_id_mixer(card, name: src); |
1988 | if (kctl) { |
1989 | snd_ctl_rename(card, kctl, name: dst); |
1990 | return 0; |
1991 | } |
1992 | return -ENOENT; |
1993 | } |
1994 | |
1995 | int snd_emu10k1_mixer(struct snd_emu10k1 *emu, |
1996 | int pcm_device, int multi_device) |
1997 | { |
1998 | int err; |
1999 | struct snd_kcontrol *kctl; |
2000 | struct snd_card *card = emu->card; |
2001 | const char * const *c; |
2002 | static const char * const emu10k1_remove_ctls[] = { |
2003 | /* no AC97 mono, surround, center/lfe */ |
2004 | "Master Mono Playback Switch" , |
2005 | "Master Mono Playback Volume" , |
2006 | "PCM Out Path & Mute" , |
2007 | "Mono Output Select" , |
2008 | "Surround Playback Switch" , |
2009 | "Surround Playback Volume" , |
2010 | "Center Playback Switch" , |
2011 | "Center Playback Volume" , |
2012 | "LFE Playback Switch" , |
2013 | "LFE Playback Volume" , |
2014 | NULL |
2015 | }; |
2016 | static const char * const emu10k1_rename_ctls[] = { |
2017 | "Surround Digital Playback Volume" , "Surround Playback Volume" , |
2018 | "Center Digital Playback Volume" , "Center Playback Volume" , |
2019 | "LFE Digital Playback Volume" , "LFE Playback Volume" , |
2020 | NULL |
2021 | }; |
2022 | static const char * const audigy_remove_ctls[] = { |
2023 | /* Master/PCM controls on ac97 of Audigy has no effect */ |
2024 | /* On the Audigy2 the AC97 playback is piped into |
2025 | * the Philips ADC for 24bit capture */ |
2026 | "PCM Playback Switch" , |
2027 | "PCM Playback Volume" , |
2028 | "Master Playback Switch" , |
2029 | "Master Playback Volume" , |
2030 | "PCM Out Path & Mute" , |
2031 | "Mono Output Select" , |
2032 | /* remove unused AC97 capture controls */ |
2033 | "Capture Source" , |
2034 | "Capture Switch" , |
2035 | "Capture Volume" , |
2036 | "Mic Select" , |
2037 | "Headphone Playback Switch" , |
2038 | "Headphone Playback Volume" , |
2039 | "3D Control - Center" , |
2040 | "3D Control - Depth" , |
2041 | "3D Control - Switch" , |
2042 | "Video Playback Switch" , |
2043 | "Video Playback Volume" , |
2044 | "Mic Playback Switch" , |
2045 | "Mic Playback Volume" , |
2046 | "External Amplifier" , |
2047 | NULL |
2048 | }; |
2049 | static const char * const audigy_rename_ctls[] = { |
2050 | /* use conventional names */ |
2051 | "Wave Playback Volume" , "PCM Playback Volume" , |
2052 | /* "Wave Capture Volume", "PCM Capture Volume", */ |
2053 | "Wave Master Playback Volume" , "Master Playback Volume" , |
2054 | "AMic Playback Volume" , "Mic Playback Volume" , |
2055 | "Master Mono Playback Switch" , "Phone Output Playback Switch" , |
2056 | "Master Mono Playback Volume" , "Phone Output Playback Volume" , |
2057 | NULL |
2058 | }; |
2059 | static const char * const audigy_rename_ctls_i2c_adc[] = { |
2060 | //"Analog Mix Capture Volume","OLD Analog Mix Capture Volume", |
2061 | "Line Capture Volume" , "Analog Mix Capture Volume" , |
2062 | "Wave Playback Volume" , "OLD PCM Playback Volume" , |
2063 | "Wave Master Playback Volume" , "Master Playback Volume" , |
2064 | "AMic Playback Volume" , "Old Mic Playback Volume" , |
2065 | "CD Capture Volume" , "IEC958 Optical Capture Volume" , |
2066 | NULL |
2067 | }; |
2068 | static const char * const audigy_remove_ctls_i2c_adc[] = { |
2069 | /* On the Audigy2 ZS Notebook |
2070 | * Capture via WM8775 */ |
2071 | "Mic Capture Volume" , |
2072 | "Analog Mix Capture Volume" , |
2073 | "Aux Capture Volume" , |
2074 | "IEC958 Optical Capture Volume" , |
2075 | NULL |
2076 | }; |
2077 | static const char * const audigy_remove_ctls_1361t_adc[] = { |
2078 | /* On the Audigy2 the AC97 playback is piped into |
2079 | * the Philips ADC for 24bit capture */ |
2080 | "PCM Playback Switch" , |
2081 | "PCM Playback Volume" , |
2082 | "Capture Source" , |
2083 | "Capture Switch" , |
2084 | "Capture Volume" , |
2085 | "Mic Capture Volume" , |
2086 | "Headphone Playback Switch" , |
2087 | "Headphone Playback Volume" , |
2088 | "3D Control - Center" , |
2089 | "3D Control - Depth" , |
2090 | "3D Control - Switch" , |
2091 | "Line2 Playback Volume" , |
2092 | "Line2 Capture Volume" , |
2093 | NULL |
2094 | }; |
2095 | static const char * const audigy_rename_ctls_1361t_adc[] = { |
2096 | "Master Playback Switch" , "Master Capture Switch" , |
2097 | "Master Playback Volume" , "Master Capture Volume" , |
2098 | "Wave Master Playback Volume" , "Master Playback Volume" , |
2099 | "Beep Playback Switch" , "Beep Capture Switch" , |
2100 | "Beep Playback Volume" , "Beep Capture Volume" , |
2101 | "Phone Playback Switch" , "Phone Capture Switch" , |
2102 | "Phone Playback Volume" , "Phone Capture Volume" , |
2103 | "Mic Playback Switch" , "Mic Capture Switch" , |
2104 | "Mic Playback Volume" , "Mic Capture Volume" , |
2105 | "Line Playback Switch" , "Line Capture Switch" , |
2106 | "Line Playback Volume" , "Line Capture Volume" , |
2107 | "CD Playback Switch" , "CD Capture Switch" , |
2108 | "CD Playback Volume" , "CD Capture Volume" , |
2109 | "Aux Playback Switch" , "Aux Capture Switch" , |
2110 | "Aux Playback Volume" , "Aux Capture Volume" , |
2111 | "Video Playback Switch" , "Video Capture Switch" , |
2112 | "Video Playback Volume" , "Video Capture Volume" , |
2113 | "Master Mono Playback Switch" , "Phone Output Playback Switch" , |
2114 | "Master Mono Playback Volume" , "Phone Output Playback Volume" , |
2115 | NULL |
2116 | }; |
2117 | |
2118 | if (emu->card_capabilities->ac97_chip) { |
2119 | struct snd_ac97_bus *pbus; |
2120 | struct snd_ac97_template ac97; |
2121 | static const struct snd_ac97_bus_ops ops = { |
2122 | .write = snd_emu10k1_ac97_write, |
2123 | .read = snd_emu10k1_ac97_read, |
2124 | }; |
2125 | |
2126 | err = snd_ac97_bus(card: emu->card, num: 0, ops: &ops, NULL, rbus: &pbus); |
2127 | if (err < 0) |
2128 | return err; |
2129 | pbus->no_vra = 1; /* we don't need VRA */ |
2130 | |
2131 | memset(&ac97, 0, sizeof(ac97)); |
2132 | ac97.private_data = emu; |
2133 | ac97.private_free = snd_emu10k1_mixer_free_ac97; |
2134 | ac97.scaps = AC97_SCAP_NO_SPDIF; |
2135 | err = snd_ac97_mixer(bus: pbus, template: &ac97, rac97: &emu->ac97); |
2136 | if (err < 0) { |
2137 | if (emu->card_capabilities->ac97_chip == 1) |
2138 | return err; |
2139 | dev_info(emu->card->dev, |
2140 | "AC97 is optional on this board\n" ); |
2141 | dev_info(emu->card->dev, |
2142 | "Proceeding without ac97 mixers...\n" ); |
2143 | snd_device_free(card: emu->card, device_data: pbus); |
2144 | goto no_ac97; /* FIXME: get rid of ugly gotos.. */ |
2145 | } |
2146 | if (emu->audigy) { |
2147 | /* set master volume to 0 dB */ |
2148 | snd_ac97_write_cache(ac97: emu->ac97, AC97_MASTER, value: 0x0000); |
2149 | /* set capture source to mic */ |
2150 | snd_ac97_write_cache(ac97: emu->ac97, AC97_REC_SEL, value: 0x0000); |
2151 | /* set mono output (TAD) to mic */ |
2152 | snd_ac97_update_bits(ac97: emu->ac97, AC97_GENERAL_PURPOSE, |
2153 | mask: 0x0200, value: 0x0200); |
2154 | if (emu->card_capabilities->adc_1361t) |
2155 | c = audigy_remove_ctls_1361t_adc; |
2156 | else |
2157 | c = audigy_remove_ctls; |
2158 | } else { |
2159 | /* |
2160 | * Credits for cards based on STAC9758: |
2161 | * James Courtier-Dutton <James@superbug.demon.co.uk> |
2162 | * Voluspa <voluspa@comhem.se> |
2163 | */ |
2164 | if (emu->ac97->id == AC97_ID_STAC9758) { |
2165 | emu->rear_ac97 = 1; |
2166 | snd_emu10k1_ptr_write(emu, AC97SLOT, chn: 0, AC97SLOT_CNTR|AC97SLOT_LFE|AC97SLOT_REAR_LEFT|AC97SLOT_REAR_RIGHT); |
2167 | snd_ac97_write_cache(ac97: emu->ac97, AC97_HEADPHONE, value: 0x0202); |
2168 | remove_ctl(card,name: "Front Playback Volume" ); |
2169 | remove_ctl(card,name: "Front Playback Switch" ); |
2170 | } |
2171 | /* remove unused AC97 controls */ |
2172 | snd_ac97_write_cache(ac97: emu->ac97, AC97_SURROUND_MASTER, value: 0x0202); |
2173 | snd_ac97_write_cache(ac97: emu->ac97, AC97_CENTER_LFE_MASTER, value: 0x0202); |
2174 | c = emu10k1_remove_ctls; |
2175 | } |
2176 | for (; *c; c++) |
2177 | remove_ctl(card, name: *c); |
2178 | } else if (emu->card_capabilities->i2c_adc) { |
2179 | c = audigy_remove_ctls_i2c_adc; |
2180 | for (; *c; c++) |
2181 | remove_ctl(card, name: *c); |
2182 | } else { |
2183 | no_ac97: |
2184 | if (emu->card_capabilities->ecard) |
2185 | strcpy(p: emu->card->mixername, q: "EMU APS" ); |
2186 | else if (emu->audigy) |
2187 | strcpy(p: emu->card->mixername, q: "SB Audigy" ); |
2188 | else |
2189 | strcpy(p: emu->card->mixername, q: "Emu10k1" ); |
2190 | } |
2191 | |
2192 | if (emu->audigy) |
2193 | if (emu->card_capabilities->adc_1361t) |
2194 | c = audigy_rename_ctls_1361t_adc; |
2195 | else if (emu->card_capabilities->i2c_adc) |
2196 | c = audigy_rename_ctls_i2c_adc; |
2197 | else |
2198 | c = audigy_rename_ctls; |
2199 | else |
2200 | c = emu10k1_rename_ctls; |
2201 | for (; *c; c += 2) |
2202 | rename_ctl(card, src: c[0], dst: c[1]); |
2203 | |
2204 | if (emu->card_capabilities->subsystem == 0x80401102) { /* SB Live! Platinum CT4760P */ |
2205 | remove_ctl(card, name: "Center Playback Volume" ); |
2206 | remove_ctl(card, name: "LFE Playback Volume" ); |
2207 | remove_ctl(card, name: "Wave Center Playback Volume" ); |
2208 | remove_ctl(card, name: "Wave LFE Playback Volume" ); |
2209 | } |
2210 | if (emu->card_capabilities->subsystem == 0x20071102) { /* Audigy 4 Pro */ |
2211 | rename_ctl(card, src: "Line2 Capture Volume" , dst: "Line1/Mic Capture Volume" ); |
2212 | rename_ctl(card, src: "Analog Mix Capture Volume" , dst: "Line2 Capture Volume" ); |
2213 | rename_ctl(card, src: "Aux2 Capture Volume" , dst: "Line3 Capture Volume" ); |
2214 | rename_ctl(card, src: "Mic Capture Volume" , dst: "Unknown1 Capture Volume" ); |
2215 | } |
2216 | kctl = emu->ctl_send_routing = snd_ctl_new1(kcontrolnew: &snd_emu10k1_send_routing_control, private_data: emu); |
2217 | if (!kctl) |
2218 | return -ENOMEM; |
2219 | kctl->id.device = pcm_device; |
2220 | err = snd_ctl_add(card, kcontrol: kctl); |
2221 | if (err) |
2222 | return err; |
2223 | kctl = emu->ctl_send_volume = snd_ctl_new1(kcontrolnew: &snd_emu10k1_send_volume_control, private_data: emu); |
2224 | if (!kctl) |
2225 | return -ENOMEM; |
2226 | kctl->id.device = pcm_device; |
2227 | err = snd_ctl_add(card, kcontrol: kctl); |
2228 | if (err) |
2229 | return err; |
2230 | kctl = emu->ctl_attn = snd_ctl_new1(kcontrolnew: &snd_emu10k1_attn_control, private_data: emu); |
2231 | if (!kctl) |
2232 | return -ENOMEM; |
2233 | kctl->id.device = pcm_device; |
2234 | err = snd_ctl_add(card, kcontrol: kctl); |
2235 | if (err) |
2236 | return err; |
2237 | |
2238 | kctl = emu->ctl_efx_send_routing = snd_ctl_new1(kcontrolnew: &snd_emu10k1_efx_send_routing_control, private_data: emu); |
2239 | if (!kctl) |
2240 | return -ENOMEM; |
2241 | kctl->id.device = multi_device; |
2242 | err = snd_ctl_add(card, kcontrol: kctl); |
2243 | if (err) |
2244 | return err; |
2245 | |
2246 | kctl = emu->ctl_efx_send_volume = snd_ctl_new1(kcontrolnew: &snd_emu10k1_efx_send_volume_control, private_data: emu); |
2247 | if (!kctl) |
2248 | return -ENOMEM; |
2249 | kctl->id.device = multi_device; |
2250 | err = snd_ctl_add(card, kcontrol: kctl); |
2251 | if (err) |
2252 | return err; |
2253 | |
2254 | kctl = emu->ctl_efx_attn = snd_ctl_new1(kcontrolnew: &snd_emu10k1_efx_attn_control, private_data: emu); |
2255 | if (!kctl) |
2256 | return -ENOMEM; |
2257 | kctl->id.device = multi_device; |
2258 | err = snd_ctl_add(card, kcontrol: kctl); |
2259 | if (err) |
2260 | return err; |
2261 | |
2262 | if (!emu->card_capabilities->ecard && !emu->card_capabilities->emu_model) { |
2263 | /* sb live! and audigy */ |
2264 | kctl = snd_ctl_new1(kcontrolnew: &snd_emu10k1_spdif_mask_control, private_data: emu); |
2265 | if (!kctl) |
2266 | return -ENOMEM; |
2267 | if (!emu->audigy) |
2268 | kctl->id.device = emu->pcm_efx->device; |
2269 | err = snd_ctl_add(card, kcontrol: kctl); |
2270 | if (err) |
2271 | return err; |
2272 | kctl = snd_ctl_new1(kcontrolnew: &snd_emu10k1_spdif_control, private_data: emu); |
2273 | if (!kctl) |
2274 | return -ENOMEM; |
2275 | if (!emu->audigy) |
2276 | kctl->id.device = emu->pcm_efx->device; |
2277 | err = snd_ctl_add(card, kcontrol: kctl); |
2278 | if (err) |
2279 | return err; |
2280 | } |
2281 | |
2282 | if (emu->card_capabilities->emu_model) { |
2283 | ; /* Disable the snd_audigy_spdif_shared_spdif */ |
2284 | } else if (emu->audigy) { |
2285 | kctl = snd_ctl_new1(kcontrolnew: &snd_audigy_shared_spdif, private_data: emu); |
2286 | if (!kctl) |
2287 | return -ENOMEM; |
2288 | err = snd_ctl_add(card, kcontrol: kctl); |
2289 | if (err) |
2290 | return err; |
2291 | #if 0 |
2292 | kctl = snd_ctl_new1(&snd_audigy_spdif_output_rate, emu); |
2293 | if (!kctl) |
2294 | return -ENOMEM; |
2295 | err = snd_ctl_add(card, kctl); |
2296 | if (err) |
2297 | return err; |
2298 | #endif |
2299 | } else if (! emu->card_capabilities->ecard) { |
2300 | /* sb live! */ |
2301 | kctl = snd_ctl_new1(kcontrolnew: &snd_emu10k1_shared_spdif, private_data: emu); |
2302 | if (!kctl) |
2303 | return -ENOMEM; |
2304 | err = snd_ctl_add(card, kcontrol: kctl); |
2305 | if (err) |
2306 | return err; |
2307 | } |
2308 | if (emu->card_capabilities->ca0151_chip) { /* P16V */ |
2309 | err = snd_p16v_mixer(emu); |
2310 | if (err) |
2311 | return err; |
2312 | } |
2313 | |
2314 | if (emu->card_capabilities->emu_model) { |
2315 | unsigned i, emu_idx = emu1010_idx(emu); |
2316 | const struct snd_emu1010_routing_info *emu_ri = |
2317 | &emu1010_routing_info[emu_idx]; |
2318 | const struct snd_emu1010_pads_info *emu_pi = &emu1010_pads_info[emu_idx]; |
2319 | |
2320 | for (i = 0; i < emu_ri->n_ins; i++) |
2321 | emu->emu1010.input_source[i] = |
2322 | emu1010_map_source(emu_ri, val: emu_ri->in_dflts[i]); |
2323 | for (i = 0; i < emu_ri->n_outs; i++) |
2324 | emu->emu1010.output_source[i] = |
2325 | emu1010_map_source(emu_ri, val: emu_ri->out_dflts[i]); |
2326 | snd_emu1010_apply_sources(emu); |
2327 | |
2328 | kctl = emu->ctl_clock_source = snd_ctl_new1(kcontrolnew: &snd_emu1010_clock_source, private_data: emu); |
2329 | err = snd_ctl_add(card, kcontrol: kctl); |
2330 | if (err < 0) |
2331 | return err; |
2332 | err = snd_ctl_add(card, |
2333 | kcontrol: snd_ctl_new1(kcontrolnew: &snd_emu1010_clock_fallback, private_data: emu)); |
2334 | if (err < 0) |
2335 | return err; |
2336 | |
2337 | err = add_ctls(emu, tpl: &emu1010_adc_pads_ctl, |
2338 | ctls: emu_pi->adc_ctls, nctls: emu_pi->n_adc_ctls); |
2339 | if (err < 0) |
2340 | return err; |
2341 | err = add_ctls(emu, tpl: &emu1010_dac_pads_ctl, |
2342 | ctls: emu_pi->dac_ctls, nctls: emu_pi->n_dac_ctls); |
2343 | if (err < 0) |
2344 | return err; |
2345 | |
2346 | if (!emu->card_capabilities->no_adat) { |
2347 | err = snd_ctl_add(card, |
2348 | kcontrol: snd_ctl_new1(kcontrolnew: &snd_emu1010_optical_out, private_data: emu)); |
2349 | if (err < 0) |
2350 | return err; |
2351 | err = snd_ctl_add(card, |
2352 | kcontrol: snd_ctl_new1(kcontrolnew: &snd_emu1010_optical_in, private_data: emu)); |
2353 | if (err < 0) |
2354 | return err; |
2355 | } |
2356 | |
2357 | err = add_emu1010_source_mixers(emu); |
2358 | if (err < 0) |
2359 | return err; |
2360 | } |
2361 | |
2362 | if ( emu->card_capabilities->i2c_adc) { |
2363 | err = snd_ctl_add(card, kcontrol: snd_ctl_new1(kcontrolnew: &snd_audigy_i2c_capture_source, private_data: emu)); |
2364 | if (err < 0) |
2365 | return err; |
2366 | |
2367 | err = add_ctls(emu, tpl: &i2c_volume_ctl, |
2368 | ctls: snd_audigy_i2c_volume_ctls, |
2369 | ARRAY_SIZE(snd_audigy_i2c_volume_ctls)); |
2370 | if (err < 0) |
2371 | return err; |
2372 | } |
2373 | |
2374 | if (emu->card_capabilities->ac97_chip && emu->audigy) { |
2375 | err = snd_ctl_add(card, kcontrol: snd_ctl_new1(kcontrolnew: &snd_audigy_capture_boost, |
2376 | private_data: emu)); |
2377 | if (err < 0) |
2378 | return err; |
2379 | } |
2380 | |
2381 | return 0; |
2382 | } |
2383 | |