1 // SPDX-License-Identifier: GPL-2.0-or-later
2 /*
3 * Tascam US-16x08 ALSA driver
4 *
5 * Copyright (c) 2016 by Detlef Urban (onkel@paraair.de)
6 */
7
8 #include <linux/slab.h>
9 #include <linux/usb.h>
10 #include <linux/usb/audio-v2.h>
11
12 #include <sound/core.h>
13 #include <sound/control.h>
14
15 #include "usbaudio.h"
16 #include "mixer.h"
17 #include "helper.h"
18
19 #include "mixer_us16x08.h"
20
21 /* USB control message templates */
22 static const char route_msg[] = {
23 0x61,
24 0x02,
25 0x03, /* input from master (0x02) or input from computer bus (0x03) */
26 0x62,
27 0x02,
28 0x01, /* input index (0x01/0x02 eq. left/right) or bus (0x01-0x08) */
29 0x41,
30 0x01,
31 0x61,
32 0x02,
33 0x01,
34 0x62,
35 0x02,
36 0x01, /* output index (0x01-0x08) */
37 0x42,
38 0x01,
39 0x43,
40 0x01,
41 0x00,
42 0x00
43 };
44
45 static const char mix_init_msg1[] = {
46 0x71, 0x01, 0x00, 0x00
47 };
48
49 static const char mix_init_msg2[] = {
50 0x62, 0x02, 0x00, 0x61, 0x02, 0x04, 0xb1, 0x01, 0x00, 0x00
51 };
52
53 static const char mix_msg_in[] = {
54 /* default message head, equal to all mixers */
55 0x61, 0x02, 0x04, 0x62, 0x02, 0x01,
56 0x81, /* 0x06: Controller ID */
57 0x02, /* 0x07: */
58 0x00, /* 0x08: Value of common mixer */
59 0x00,
60 0x00
61 };
62
63 static const char mix_msg_out[] = {
64 /* default message head, equal to all mixers */
65 0x61, 0x02, 0x02, 0x62, 0x02, 0x01,
66 0x81, /* 0x06: Controller ID */
67 0x02, /* 0x07: */
68 0x00, /* 0x08: Value of common mixer */
69 0x00,
70 0x00
71 };
72
73 static const char bypass_msg_out[] = {
74 0x45,
75 0x02,
76 0x01, /* on/off flag */
77 0x00,
78 0x00
79 };
80
81 static const char bus_msg_out[] = {
82 0x44,
83 0x02,
84 0x01, /* on/off flag */
85 0x00,
86 0x00
87 };
88
89 static const char comp_msg[] = {
90 /* default message head, equal to all mixers */
91 0x61, 0x02, 0x04, 0x62, 0x02, 0x01,
92 0x91,
93 0x02,
94 0xf0, /* 0x08: Threshold db (8) (e0 ... 00) (+-0dB -- -32dB) x-32 */
95 0x92,
96 0x02,
97 0x0a, /* 0x0b: Ratio (0a,0b,0d,0f,11,14,19,1e,23,28,32,3c,50,a0,ff) */
98 0x93,
99 0x02,
100 0x02, /* 0x0e: Attack (0x02 ... 0xc0) (2ms ... 200ms) */
101 0x94,
102 0x02,
103 0x01, /* 0x11: Release (0x01 ... 0x64) (10ms ... 1000ms) x*10 */
104 0x95,
105 0x02,
106 0x03, /* 0x14: gain (0 ... 20) (0dB .. 20dB) */
107 0x96,
108 0x02,
109 0x01,
110 0x97,
111 0x02,
112 0x01, /* 0x1a: main Comp switch (0 ... 1) (off ... on)) */
113 0x00,
114 0x00
115 };
116
117 static const char eqs_msq[] = {
118 /* default message head, equal to all mixers */
119 0x61, 0x02, 0x04, 0x62, 0x02, 0x01,
120 0x51, /* 0x06: Controller ID */
121 0x02,
122 0x04, /* 0x08: EQ set num (0x01..0x04) (LOW, LOWMID, HIGHMID, HIGH)) */
123 0x52,
124 0x02,
125 0x0c, /* 0x0b: value dB (0 ... 12) (-12db .. +12db) x-6 */
126 0x53,
127 0x02,
128 0x0f, /* 0x0e: value freq (32-47) (1.7kHz..18kHz) */
129 0x54,
130 0x02,
131 0x02, /* 0x11: band width (0-6) (Q16-Q0.25) 2^x/4 (EQ xxMID only) */
132 0x55,
133 0x02,
134 0x01, /* 0x14: main EQ switch (0 ... 1) (off ... on)) */
135 0x00,
136 0x00
137 };
138
139 /* compressor ratio map */
140 static const char ratio_map[] = {
141 0x0a, 0x0b, 0x0d, 0x0f, 0x11, 0x14, 0x19, 0x1e,
142 0x23, 0x28, 0x32, 0x3c, 0x50, 0xa0, 0xff
143 };
144
145 /* route enumeration names */
146 static const char *const route_names[] = {
147 "Master Left", "Master Right", "Output 1", "Output 2", "Output 3",
148 "Output 4", "Output 5", "Output 6", "Output 7", "Output 8",
149 };
150
snd_us16x08_recv_urb(struct snd_usb_audio * chip,unsigned char * buf,int size)151 static int snd_us16x08_recv_urb(struct snd_usb_audio *chip,
152 unsigned char *buf, int size)
153 {
154
155 guard(mutex)(&chip->mutex);
156 snd_usb_ctl_msg(chip->dev,
157 usb_rcvctrlpipe(chip->dev, 0),
158 SND_US16X08_URB_METER_REQUEST,
159 SND_US16X08_URB_METER_REQUESTTYPE, 0, 0, buf, size);
160 return 0;
161 }
162
163 /* wrapper function to send prepared URB buffer to usb device. Return an error
164 * code if something went wrong
165 */
snd_us16x08_send_urb(struct snd_usb_audio * chip,char * buf,int size)166 static int snd_us16x08_send_urb(struct snd_usb_audio *chip, char *buf, int size)
167 {
168 return snd_usb_ctl_msg(chip->dev, usb_sndctrlpipe(chip->dev, 0),
169 SND_US16X08_URB_REQUEST, SND_US16X08_URB_REQUESTTYPE,
170 0, 0, buf, size);
171 }
172
snd_us16x08_route_info(struct snd_kcontrol * kcontrol,struct snd_ctl_elem_info * uinfo)173 static int snd_us16x08_route_info(struct snd_kcontrol *kcontrol,
174 struct snd_ctl_elem_info *uinfo)
175 {
176 return snd_ctl_enum_info(uinfo, 1, 10, route_names);
177 }
178
snd_us16x08_route_get(struct snd_kcontrol * kcontrol,struct snd_ctl_elem_value * ucontrol)179 static int snd_us16x08_route_get(struct snd_kcontrol *kcontrol,
180 struct snd_ctl_elem_value *ucontrol)
181 {
182 struct usb_mixer_elem_info *elem = snd_kcontrol_chip(kcontrol);
183 int index = ucontrol->id.index;
184
185 /* route has no bias */
186 ucontrol->value.enumerated.item[0] = elem->cache_val[index];
187
188 return 0;
189 }
190
snd_us16x08_route_put(struct snd_kcontrol * kcontrol,struct snd_ctl_elem_value * ucontrol)191 static int snd_us16x08_route_put(struct snd_kcontrol *kcontrol,
192 struct snd_ctl_elem_value *ucontrol)
193 {
194 struct usb_mixer_elem_info *elem = snd_kcontrol_chip(kcontrol);
195 struct snd_usb_audio *chip = elem->head.mixer->chip;
196 int index = ucontrol->id.index;
197 char buf[sizeof(route_msg)];
198 int val, val_org, err;
199
200 /* get the new value (no bias for routes) */
201 val = ucontrol->value.enumerated.item[0];
202
203 /* sanity check */
204 if (val < 0 || val > 9)
205 return -EINVAL;
206
207 /* prepare the message buffer from template */
208 memcpy(buf, route_msg, sizeof(route_msg));
209
210 if (val < 2) {
211 /* input comes from a master channel */
212 val_org = val;
213 buf[2] = 0x02;
214 } else {
215 /* input comes from a computer channel */
216 buf[2] = 0x03;
217 val_org = val - 2;
218 }
219
220 /* place new route selection in URB message */
221 buf[5] = (unsigned char) (val_org & 0x0f) + 1;
222 /* place route selector in URB message */
223 buf[13] = index + 1;
224
225 err = snd_us16x08_send_urb(chip, buf, sizeof(route_msg));
226
227 if (err > 0) {
228 elem->cached |= 1 << index;
229 elem->cache_val[index] = val;
230 } else {
231 usb_audio_dbg(chip, "Failed to set routing, err:%d\n", err);
232 }
233
234 return err > 0 ? 1 : 0;
235 }
236
snd_us16x08_master_info(struct snd_kcontrol * kcontrol,struct snd_ctl_elem_info * uinfo)237 static int snd_us16x08_master_info(struct snd_kcontrol *kcontrol,
238 struct snd_ctl_elem_info *uinfo)
239 {
240 uinfo->count = 1;
241 uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
242 uinfo->value.integer.max = SND_US16X08_KCMAX(kcontrol);
243 uinfo->value.integer.min = SND_US16X08_KCMIN(kcontrol);
244 uinfo->value.integer.step = SND_US16X08_KCSTEP(kcontrol);
245 return 0;
246 }
247
snd_us16x08_master_get(struct snd_kcontrol * kcontrol,struct snd_ctl_elem_value * ucontrol)248 static int snd_us16x08_master_get(struct snd_kcontrol *kcontrol,
249 struct snd_ctl_elem_value *ucontrol)
250 {
251 struct usb_mixer_elem_info *elem = snd_kcontrol_chip(kcontrol);
252 int index = ucontrol->id.index;
253
254 ucontrol->value.integer.value[0] = elem->cache_val[index];
255
256 return 0;
257 }
258
snd_us16x08_master_put(struct snd_kcontrol * kcontrol,struct snd_ctl_elem_value * ucontrol)259 static int snd_us16x08_master_put(struct snd_kcontrol *kcontrol,
260 struct snd_ctl_elem_value *ucontrol)
261 {
262 struct usb_mixer_elem_info *elem = snd_kcontrol_chip(kcontrol);
263 struct snd_usb_audio *chip = elem->head.mixer->chip;
264 char buf[sizeof(mix_msg_out)];
265 int val, err;
266 int index = ucontrol->id.index;
267
268 /* new control value incl. bias*/
269 val = ucontrol->value.integer.value[0];
270
271 /* sanity check */
272 if (val < SND_US16X08_KCMIN(kcontrol)
273 || val > SND_US16X08_KCMAX(kcontrol))
274 return -EINVAL;
275
276 /* prepare the message buffer from template */
277 memcpy(buf, mix_msg_out, sizeof(mix_msg_out));
278
279 buf[8] = val - SND_US16X08_KCBIAS(kcontrol);
280 buf[6] = elem->head.id;
281
282 /* place channel selector in URB message */
283 buf[5] = index + 1;
284 err = snd_us16x08_send_urb(chip, buf, sizeof(mix_msg_out));
285
286 if (err > 0) {
287 elem->cached |= 1 << index;
288 elem->cache_val[index] = val;
289 } else {
290 usb_audio_dbg(chip, "Failed to set master, err:%d\n", err);
291 }
292
293 return err > 0 ? 1 : 0;
294 }
295
snd_us16x08_bus_put(struct snd_kcontrol * kcontrol,struct snd_ctl_elem_value * ucontrol)296 static int snd_us16x08_bus_put(struct snd_kcontrol *kcontrol,
297 struct snd_ctl_elem_value *ucontrol)
298 {
299 struct usb_mixer_elem_info *elem = snd_kcontrol_chip(kcontrol);
300 struct snd_usb_audio *chip = elem->head.mixer->chip;
301 char buf[sizeof(mix_msg_out)];
302 int val, err = 0;
303
304 val = ucontrol->value.integer.value[0];
305
306 /* prepare the message buffer from template */
307 switch (elem->head.id) {
308 case SND_US16X08_ID_BYPASS:
309 memcpy(buf, bypass_msg_out, sizeof(bypass_msg_out));
310 buf[2] = val;
311 err = snd_us16x08_send_urb(chip, buf, sizeof(bypass_msg_out));
312 break;
313 case SND_US16X08_ID_BUSS_OUT:
314 memcpy(buf, bus_msg_out, sizeof(bus_msg_out));
315 buf[2] = val;
316 err = snd_us16x08_send_urb(chip, buf, sizeof(bus_msg_out));
317 break;
318 case SND_US16X08_ID_MUTE:
319 memcpy(buf, mix_msg_out, sizeof(mix_msg_out));
320 buf[8] = val;
321 buf[6] = elem->head.id;
322 buf[5] = 1;
323 err = snd_us16x08_send_urb(chip, buf, sizeof(mix_msg_out));
324 break;
325 }
326
327 if (err > 0) {
328 elem->cached |= 1;
329 elem->cache_val[0] = val;
330 } else {
331 usb_audio_dbg(chip, "Failed to set bus parameter, err:%d\n", err);
332 }
333
334 return err > 0 ? 1 : 0;
335 }
336
snd_us16x08_bus_get(struct snd_kcontrol * kcontrol,struct snd_ctl_elem_value * ucontrol)337 static int snd_us16x08_bus_get(struct snd_kcontrol *kcontrol,
338 struct snd_ctl_elem_value *ucontrol)
339 {
340 struct usb_mixer_elem_info *elem = snd_kcontrol_chip(kcontrol);
341
342 switch (elem->head.id) {
343 case SND_US16X08_ID_BUSS_OUT:
344 ucontrol->value.integer.value[0] = elem->cache_val[0];
345 break;
346 case SND_US16X08_ID_BYPASS:
347 ucontrol->value.integer.value[0] = elem->cache_val[0];
348 break;
349 case SND_US16X08_ID_MUTE:
350 ucontrol->value.integer.value[0] = elem->cache_val[0];
351 break;
352 }
353
354 return 0;
355 }
356
357 /* gets a current mixer value from common store */
snd_us16x08_channel_get(struct snd_kcontrol * kcontrol,struct snd_ctl_elem_value * ucontrol)358 static int snd_us16x08_channel_get(struct snd_kcontrol *kcontrol,
359 struct snd_ctl_elem_value *ucontrol)
360 {
361 struct usb_mixer_elem_info *elem = snd_kcontrol_chip(kcontrol);
362 int index = ucontrol->id.index;
363
364 ucontrol->value.integer.value[0] = elem->cache_val[index];
365
366 return 0;
367 }
368
snd_us16x08_channel_put(struct snd_kcontrol * kcontrol,struct snd_ctl_elem_value * ucontrol)369 static int snd_us16x08_channel_put(struct snd_kcontrol *kcontrol,
370 struct snd_ctl_elem_value *ucontrol)
371 {
372 struct usb_mixer_elem_info *elem = snd_kcontrol_chip(kcontrol);
373 struct snd_usb_audio *chip = elem->head.mixer->chip;
374 char buf[sizeof(mix_msg_in)];
375 int val, err;
376 int index = ucontrol->id.index;
377
378 val = ucontrol->value.integer.value[0];
379
380 /* sanity check */
381 if (val < SND_US16X08_KCMIN(kcontrol)
382 || val > SND_US16X08_KCMAX(kcontrol))
383 return -EINVAL;
384
385 /* prepare URB message from template */
386 memcpy(buf, mix_msg_in, sizeof(mix_msg_in));
387
388 /* add the bias to the new value */
389 buf[8] = val - SND_US16X08_KCBIAS(kcontrol);
390 buf[6] = elem->head.id;
391 buf[5] = index + 1;
392
393 err = snd_us16x08_send_urb(chip, buf, sizeof(mix_msg_in));
394
395 if (err > 0) {
396 elem->cached |= 1 << index;
397 elem->cache_val[index] = val;
398 } else {
399 usb_audio_dbg(chip, "Failed to set channel, err:%d\n", err);
400 }
401
402 return err > 0 ? 1 : 0;
403 }
404
snd_us16x08_mix_info(struct snd_kcontrol * kcontrol,struct snd_ctl_elem_info * uinfo)405 static int snd_us16x08_mix_info(struct snd_kcontrol *kcontrol,
406 struct snd_ctl_elem_info *uinfo)
407 {
408 uinfo->count = 1;
409 uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
410 uinfo->value.integer.max = SND_US16X08_KCMAX(kcontrol);
411 uinfo->value.integer.min = SND_US16X08_KCMIN(kcontrol);
412 uinfo->value.integer.step = SND_US16X08_KCSTEP(kcontrol);
413 return 0;
414 }
415
snd_us16x08_comp_get(struct snd_kcontrol * kcontrol,struct snd_ctl_elem_value * ucontrol)416 static int snd_us16x08_comp_get(struct snd_kcontrol *kcontrol,
417 struct snd_ctl_elem_value *ucontrol)
418 {
419 struct usb_mixer_elem_info *elem = snd_kcontrol_chip(kcontrol);
420 struct snd_us16x08_comp_store *store = elem->private_data;
421 int index = ucontrol->id.index;
422 int val_idx = COMP_STORE_IDX(elem->head.id);
423
424 ucontrol->value.integer.value[0] = store->val[val_idx][index];
425
426 return 0;
427 }
428
snd_us16x08_comp_put(struct snd_kcontrol * kcontrol,struct snd_ctl_elem_value * ucontrol)429 static int snd_us16x08_comp_put(struct snd_kcontrol *kcontrol,
430 struct snd_ctl_elem_value *ucontrol)
431 {
432 struct usb_mixer_elem_info *elem = snd_kcontrol_chip(kcontrol);
433 struct snd_usb_audio *chip = elem->head.mixer->chip;
434 struct snd_us16x08_comp_store *store = elem->private_data;
435 int index = ucontrol->id.index;
436 char buf[sizeof(comp_msg)];
437 int val_idx, val;
438 int err;
439
440 val = ucontrol->value.integer.value[0];
441
442 /* sanity check */
443 if (val < SND_US16X08_KCMIN(kcontrol)
444 || val > SND_US16X08_KCMAX(kcontrol))
445 return -EINVAL;
446
447 /* new control value incl. bias*/
448 val_idx = elem->head.id - SND_US16X08_ID_COMP_BASE;
449
450 store->val[val_idx][index] = ucontrol->value.integer.value[0];
451
452 /* prepare compressor URB message from template */
453 memcpy(buf, comp_msg, sizeof(comp_msg));
454
455 /* place comp values in message buffer watch bias! */
456 buf[8] = store->val[
457 COMP_STORE_IDX(SND_US16X08_ID_COMP_THRESHOLD)][index]
458 - SND_US16X08_COMP_THRESHOLD_BIAS;
459 buf[11] = ratio_map[store->val[
460 COMP_STORE_IDX(SND_US16X08_ID_COMP_RATIO)][index]];
461 buf[14] = store->val[COMP_STORE_IDX(SND_US16X08_ID_COMP_ATTACK)][index]
462 + SND_US16X08_COMP_ATTACK_BIAS;
463 buf[17] = store->val[COMP_STORE_IDX(SND_US16X08_ID_COMP_RELEASE)][index]
464 + SND_US16X08_COMP_RELEASE_BIAS;
465 buf[20] = store->val[COMP_STORE_IDX(SND_US16X08_ID_COMP_GAIN)][index];
466 buf[26] = store->val[COMP_STORE_IDX(SND_US16X08_ID_COMP_SWITCH)][index];
467
468 /* place channel selector in message buffer */
469 buf[5] = index + 1;
470
471 err = snd_us16x08_send_urb(chip, buf, sizeof(comp_msg));
472
473 if (err > 0) {
474 elem->cached |= 1 << index;
475 elem->cache_val[index] = val;
476 } else {
477 usb_audio_dbg(chip, "Failed to set compressor, err:%d\n", err);
478 }
479
480 return 1;
481 }
482
snd_us16x08_eqswitch_get(struct snd_kcontrol * kcontrol,struct snd_ctl_elem_value * ucontrol)483 static int snd_us16x08_eqswitch_get(struct snd_kcontrol *kcontrol,
484 struct snd_ctl_elem_value *ucontrol)
485 {
486 int val;
487 struct usb_mixer_elem_info *elem = snd_kcontrol_chip(kcontrol);
488 struct snd_us16x08_eq_store *store = elem->private_data;
489 int index = ucontrol->id.index;
490
491 /* get low switch from cache is enough, cause all bands are together */
492 val = store->val[EQ_STORE_BAND_IDX(elem->head.id)]
493 [EQ_STORE_PARAM_IDX(elem->head.id)][index];
494 ucontrol->value.integer.value[0] = val;
495
496 return 0;
497 }
498
snd_us16x08_eqswitch_put(struct snd_kcontrol * kcontrol,struct snd_ctl_elem_value * ucontrol)499 static int snd_us16x08_eqswitch_put(struct snd_kcontrol *kcontrol,
500 struct snd_ctl_elem_value *ucontrol)
501 {
502 struct usb_mixer_elem_info *elem = snd_kcontrol_chip(kcontrol);
503 struct snd_usb_audio *chip = elem->head.mixer->chip;
504 struct snd_us16x08_eq_store *store = elem->private_data;
505 int index = ucontrol->id.index;
506 char buf[sizeof(eqs_msq)];
507 int val, err = 0;
508 int b_idx;
509
510 /* new control value incl. bias*/
511 val = ucontrol->value.integer.value[0] + SND_US16X08_KCBIAS(kcontrol);
512
513 /* prepare URB message from EQ template */
514 memcpy(buf, eqs_msq, sizeof(eqs_msq));
515
516 /* place channel index in URB message */
517 buf[5] = index + 1;
518 for (b_idx = 0; b_idx < SND_US16X08_ID_EQ_BAND_COUNT; b_idx++) {
519 /* all four EQ bands have to be enabled/disabled in once */
520 buf[20] = val;
521 buf[17] = store->val[b_idx][2][index];
522 buf[14] = store->val[b_idx][1][index];
523 buf[11] = store->val[b_idx][0][index];
524 buf[8] = b_idx + 1;
525 err = snd_us16x08_send_urb(chip, buf, sizeof(eqs_msq));
526 if (err < 0)
527 break;
528 store->val[b_idx][3][index] = val;
529 msleep(15);
530 }
531
532 if (err > 0) {
533 elem->cached |= 1 << index;
534 elem->cache_val[index] = val;
535 } else {
536 usb_audio_dbg(chip, "Failed to set eq switch, err:%d\n", err);
537 }
538
539 return 1;
540 }
541
snd_us16x08_eq_get(struct snd_kcontrol * kcontrol,struct snd_ctl_elem_value * ucontrol)542 static int snd_us16x08_eq_get(struct snd_kcontrol *kcontrol,
543 struct snd_ctl_elem_value *ucontrol)
544 {
545 int val;
546 struct usb_mixer_elem_info *elem = snd_kcontrol_chip(kcontrol);
547 struct snd_us16x08_eq_store *store = elem->private_data;
548 int index = ucontrol->id.index;
549 int b_idx = EQ_STORE_BAND_IDX(elem->head.id) - 1;
550 int p_idx = EQ_STORE_PARAM_IDX(elem->head.id);
551
552 val = store->val[b_idx][p_idx][index];
553
554 ucontrol->value.integer.value[0] = val;
555
556 return 0;
557 }
558
snd_us16x08_eq_put(struct snd_kcontrol * kcontrol,struct snd_ctl_elem_value * ucontrol)559 static int snd_us16x08_eq_put(struct snd_kcontrol *kcontrol,
560 struct snd_ctl_elem_value *ucontrol)
561 {
562 struct usb_mixer_elem_info *elem = snd_kcontrol_chip(kcontrol);
563 struct snd_usb_audio *chip = elem->head.mixer->chip;
564 struct snd_us16x08_eq_store *store = elem->private_data;
565 int index = ucontrol->id.index;
566 char buf[sizeof(eqs_msq)];
567 int val, err;
568 int b_idx = EQ_STORE_BAND_IDX(elem->head.id) - 1;
569 int p_idx = EQ_STORE_PARAM_IDX(elem->head.id);
570
571 val = ucontrol->value.integer.value[0];
572
573 /* sanity check */
574 if (val < SND_US16X08_KCMIN(kcontrol)
575 || val > SND_US16X08_KCMAX(kcontrol))
576 return -EINVAL;
577
578 /* copy URB buffer from EQ template */
579 memcpy(buf, eqs_msq, sizeof(eqs_msq));
580
581 store->val[b_idx][p_idx][index] = val;
582 buf[20] = store->val[b_idx][3][index];
583 buf[17] = store->val[b_idx][2][index];
584 buf[14] = store->val[b_idx][1][index];
585 buf[11] = store->val[b_idx][0][index];
586
587 /* place channel index in URB buffer */
588 buf[5] = index + 1;
589
590 /* place EQ band in URB buffer */
591 buf[8] = b_idx + 1;
592
593 err = snd_us16x08_send_urb(chip, buf, sizeof(eqs_msq));
594
595 if (err > 0) {
596 /* store new value in EQ band cache */
597 elem->cached |= 1 << index;
598 elem->cache_val[index] = val;
599 } else {
600 usb_audio_dbg(chip, "Failed to set eq param, err:%d\n", err);
601 }
602
603 return 1;
604 }
605
snd_us16x08_meter_info(struct snd_kcontrol * kcontrol,struct snd_ctl_elem_info * uinfo)606 static int snd_us16x08_meter_info(struct snd_kcontrol *kcontrol,
607 struct snd_ctl_elem_info *uinfo)
608 {
609 uinfo->count = 34;
610 uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
611 uinfo->value.integer.max = 0x7FFF;
612 uinfo->value.integer.min = 0;
613
614 return 0;
615 }
616
617 /* calculate compressor index for reduction level request */
snd_get_meter_comp_index(struct snd_us16x08_meter_store * store)618 static int snd_get_meter_comp_index(struct snd_us16x08_meter_store *store)
619 {
620 int ret;
621
622 /* any channel active */
623 if (store->comp_active_index) {
624 /* check for stereo link */
625 if (store->comp_active_index & 0x20) {
626 /* reset comp_index to left channel*/
627 if (store->comp_index -
628 store->comp_active_index > 1)
629 store->comp_index =
630 store->comp_active_index;
631
632 ret = store->comp_index++ & 0x1F;
633 } else {
634 /* no stereo link */
635 ret = store->comp_active_index;
636 }
637 } else {
638 /* skip channels with no compressor active */
639 while (store->comp_index <= SND_US16X08_MAX_CHANNELS
640 && !store->comp_store->val[
641 COMP_STORE_IDX(SND_US16X08_ID_COMP_SWITCH)]
642 [store->comp_index - 1]) {
643 store->comp_index++;
644 }
645 ret = store->comp_index++;
646 if (store->comp_index > SND_US16X08_MAX_CHANNELS)
647 store->comp_index = 1;
648 }
649 return ret;
650 }
651
652 /* retrieve the meter level values from URB message */
get_meter_levels_from_urb(int s,struct snd_us16x08_meter_store * store,u8 * meter_urb)653 static void get_meter_levels_from_urb(int s,
654 struct snd_us16x08_meter_store *store,
655 u8 *meter_urb)
656 {
657 int val = MUC2(meter_urb, s) + (MUC3(meter_urb, s) << 8);
658 int ch = MUB2(meter_urb, s) - 1;
659
660 if (ch < 0)
661 return;
662
663 if (MUA0(meter_urb, s) == 0x61 && MUA1(meter_urb, s) == 0x02 &&
664 MUA2(meter_urb, s) == 0x04 && MUB0(meter_urb, s) == 0x62) {
665 if (ch < SND_US16X08_MAX_CHANNELS) {
666 if (MUC0(meter_urb, s) == 0x72)
667 store->meter_level[ch] = val;
668 if (MUC0(meter_urb, s) == 0xb2)
669 store->comp_level[ch] = val;
670 }
671 }
672 if (MUA0(meter_urb, s) == 0x61 && MUA1(meter_urb, s) == 0x02 &&
673 MUA2(meter_urb, s) == 0x02 && MUB0(meter_urb, s) == 0x62) {
674 if (ch < ARRAY_SIZE(store->master_level))
675 store->master_level[ch] = val;
676 }
677 }
678
679 /* Function to retrieve current meter values from the device.
680 *
681 * The device needs to be polled for meter values with an initial
682 * requests. It will return with a sequence of different meter value
683 * packages. The first request (case 0:) initiate this meter response sequence.
684 * After the third response, an additional request can be placed,
685 * to retrieve compressor reduction level value for given channel. This round
686 * trip channel selector will skip all inactive compressors.
687 * A mixer can interrupt this round-trip by selecting one ore two (stereo-link)
688 * specific channels.
689 */
snd_us16x08_meter_get(struct snd_kcontrol * kcontrol,struct snd_ctl_elem_value * ucontrol)690 static int snd_us16x08_meter_get(struct snd_kcontrol *kcontrol,
691 struct snd_ctl_elem_value *ucontrol)
692 {
693 int i, set;
694 struct usb_mixer_elem_info *elem = snd_kcontrol_chip(kcontrol);
695 struct snd_usb_audio *chip = elem->head.mixer->chip;
696 struct snd_us16x08_meter_store *store = elem->private_data;
697 u8 meter_urb[64] = {0};
698
699 switch (kcontrol->private_value) {
700 case 0: {
701 char tmp[sizeof(mix_init_msg1)];
702
703 memcpy(tmp, mix_init_msg1, sizeof(mix_init_msg1));
704 snd_us16x08_send_urb(chip, tmp, 4);
705 snd_us16x08_recv_urb(chip, meter_urb,
706 sizeof(meter_urb));
707 kcontrol->private_value++;
708 break;
709 }
710 case 1:
711 snd_us16x08_recv_urb(chip, meter_urb,
712 sizeof(meter_urb));
713 kcontrol->private_value++;
714 break;
715 case 2:
716 snd_us16x08_recv_urb(chip, meter_urb,
717 sizeof(meter_urb));
718 kcontrol->private_value++;
719 break;
720 case 3: {
721 char tmp[sizeof(mix_init_msg2)];
722
723 memcpy(tmp, mix_init_msg2, sizeof(mix_init_msg2));
724 tmp[2] = snd_get_meter_comp_index(store);
725 snd_us16x08_send_urb(chip, tmp, 10);
726 snd_us16x08_recv_urb(chip, meter_urb,
727 sizeof(meter_urb));
728 kcontrol->private_value = 0;
729 break;
730 }
731 }
732
733 for (set = 0; set < 6; set++)
734 get_meter_levels_from_urb(set, store, meter_urb);
735
736 for (i = 0; i < SND_US16X08_MAX_CHANNELS; i++) {
737 ucontrol->value.integer.value[i] =
738 store ? store->meter_level[i] : 0;
739 }
740
741 ucontrol->value.integer.value[i++] = store ? store->master_level[0] : 0;
742 ucontrol->value.integer.value[i++] = store ? store->master_level[1] : 0;
743
744 for (i = 2; i < SND_US16X08_MAX_CHANNELS + 2; i++)
745 ucontrol->value.integer.value[i + SND_US16X08_MAX_CHANNELS] =
746 store ? store->comp_level[i - 2] : 0;
747
748 return 1;
749 }
750
snd_us16x08_meter_put(struct snd_kcontrol * kcontrol,struct snd_ctl_elem_value * ucontrol)751 static int snd_us16x08_meter_put(struct snd_kcontrol *kcontrol,
752 struct snd_ctl_elem_value *ucontrol)
753 {
754 struct usb_mixer_elem_info *elem = snd_kcontrol_chip(kcontrol);
755 struct snd_us16x08_meter_store *store = elem->private_data;
756 int val;
757
758 val = ucontrol->value.integer.value[0];
759
760 /* sanity check */
761 if (val < 0 || val >= SND_US16X08_MAX_CHANNELS)
762 return -EINVAL;
763
764 store->comp_active_index = val;
765 store->comp_index = val;
766
767 return 1;
768 }
769
770 static const struct snd_kcontrol_new snd_us16x08_ch_boolean_ctl = {
771 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
772 .access = SNDRV_CTL_ELEM_ACCESS_READWRITE,
773 .count = 16,
774 .info = snd_us16x08_switch_info,
775 .get = snd_us16x08_channel_get,
776 .put = snd_us16x08_channel_put,
777 .private_value = SND_US16X08_KCSET(SND_US16X08_NO_BIAS, 1, 0, 1)
778 };
779
780 static const struct snd_kcontrol_new snd_us16x08_ch_int_ctl = {
781 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
782 .access = SNDRV_CTL_ELEM_ACCESS_READWRITE,
783 .count = 16,
784 .info = snd_us16x08_mix_info,
785 .get = snd_us16x08_channel_get,
786 .put = snd_us16x08_channel_put,
787 .private_value = SND_US16X08_KCSET(SND_US16X08_FADER_BIAS, 1, 0, 133)
788 };
789
790 static const struct snd_kcontrol_new snd_us16x08_pan_int_ctl = {
791 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
792 .access = SNDRV_CTL_ELEM_ACCESS_READWRITE,
793 .count = 16,
794 .info = snd_us16x08_mix_info,
795 .get = snd_us16x08_channel_get,
796 .put = snd_us16x08_channel_put,
797 .private_value = SND_US16X08_KCSET(SND_US16X08_FADER_BIAS, 1, 0, 255)
798 };
799
800 static const struct snd_kcontrol_new snd_us16x08_master_ctl = {
801 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
802 .access = SNDRV_CTL_ELEM_ACCESS_READWRITE,
803 .count = 1,
804 .info = snd_us16x08_master_info,
805 .get = snd_us16x08_master_get,
806 .put = snd_us16x08_master_put,
807 .private_value = SND_US16X08_KCSET(SND_US16X08_FADER_BIAS, 1, 0, 133)
808 };
809
810 static const struct snd_kcontrol_new snd_us16x08_route_ctl = {
811 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
812 .access = SNDRV_CTL_ELEM_ACCESS_READWRITE,
813 .count = 8,
814 .info = snd_us16x08_route_info,
815 .get = snd_us16x08_route_get,
816 .put = snd_us16x08_route_put,
817 .private_value = SND_US16X08_KCSET(SND_US16X08_NO_BIAS, 1, 0, 9)
818 };
819
820 static const struct snd_kcontrol_new snd_us16x08_bus_ctl = {
821 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
822 .access = SNDRV_CTL_ELEM_ACCESS_READWRITE,
823 .count = 1,
824 .info = snd_us16x08_switch_info,
825 .get = snd_us16x08_bus_get,
826 .put = snd_us16x08_bus_put,
827 .private_value = SND_US16X08_KCSET(SND_US16X08_NO_BIAS, 1, 0, 1)
828 };
829
830 static const struct snd_kcontrol_new snd_us16x08_compswitch_ctl = {
831 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
832 .access = SNDRV_CTL_ELEM_ACCESS_READWRITE,
833 .count = 16,
834 .info = snd_us16x08_switch_info,
835 .get = snd_us16x08_comp_get,
836 .put = snd_us16x08_comp_put,
837 .private_value = SND_US16X08_KCSET(SND_US16X08_NO_BIAS, 1, 0, 1)
838 };
839
840 static const struct snd_kcontrol_new snd_us16x08_comp_threshold_ctl = {
841 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
842 .access = SNDRV_CTL_ELEM_ACCESS_READWRITE,
843 .count = 16,
844 .info = snd_us16x08_mix_info,
845 .get = snd_us16x08_comp_get,
846 .put = snd_us16x08_comp_put,
847 .private_value = SND_US16X08_KCSET(SND_US16X08_COMP_THRESHOLD_BIAS, 1,
848 0, 0x20)
849 };
850
851 static const struct snd_kcontrol_new snd_us16x08_comp_ratio_ctl = {
852 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
853 .access = SNDRV_CTL_ELEM_ACCESS_READWRITE,
854 .count = 16,
855 .info = snd_us16x08_mix_info,
856 .get = snd_us16x08_comp_get,
857 .put = snd_us16x08_comp_put,
858 .private_value = SND_US16X08_KCSET(SND_US16X08_NO_BIAS, 1, 0,
859 sizeof(ratio_map) - 1), /*max*/
860 };
861
862 static const struct snd_kcontrol_new snd_us16x08_comp_gain_ctl = {
863 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
864 .access = SNDRV_CTL_ELEM_ACCESS_READWRITE,
865 .count = 16,
866 .info = snd_us16x08_mix_info,
867 .get = snd_us16x08_comp_get,
868 .put = snd_us16x08_comp_put,
869 .private_value = SND_US16X08_KCSET(SND_US16X08_NO_BIAS, 1, 0, 0x14)
870 };
871
872 static const struct snd_kcontrol_new snd_us16x08_comp_attack_ctl = {
873 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
874 .access = SNDRV_CTL_ELEM_ACCESS_READWRITE,
875 .count = 16,
876 .info = snd_us16x08_mix_info,
877 .get = snd_us16x08_comp_get,
878 .put = snd_us16x08_comp_put,
879 .private_value =
880 SND_US16X08_KCSET(SND_US16X08_COMP_ATTACK_BIAS, 1, 0, 0xc6),
881 };
882
883 static const struct snd_kcontrol_new snd_us16x08_comp_release_ctl = {
884 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
885 .access = SNDRV_CTL_ELEM_ACCESS_READWRITE,
886 .count = 16,
887 .info = snd_us16x08_mix_info,
888 .get = snd_us16x08_comp_get,
889 .put = snd_us16x08_comp_put,
890 .private_value =
891 SND_US16X08_KCSET(SND_US16X08_COMP_RELEASE_BIAS, 1, 0, 0x63),
892 };
893
894 static const struct snd_kcontrol_new snd_us16x08_eq_gain_ctl = {
895 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
896 .access = SNDRV_CTL_ELEM_ACCESS_READWRITE,
897 .count = 16,
898 .info = snd_us16x08_mix_info,
899 .get = snd_us16x08_eq_get,
900 .put = snd_us16x08_eq_put,
901 .private_value = SND_US16X08_KCSET(SND_US16X08_NO_BIAS, 1, 0, 24),
902 };
903
904 static const struct snd_kcontrol_new snd_us16x08_eq_low_freq_ctl = {
905 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
906 .access = SNDRV_CTL_ELEM_ACCESS_READWRITE,
907 .count = 16,
908 .info = snd_us16x08_mix_info,
909 .get = snd_us16x08_eq_get,
910 .put = snd_us16x08_eq_put,
911 .private_value = SND_US16X08_KCSET(SND_US16X08_NO_BIAS, 1, 0, 0x1F),
912 };
913
914 static const struct snd_kcontrol_new snd_us16x08_eq_mid_freq_ctl = {
915 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
916 .access = SNDRV_CTL_ELEM_ACCESS_READWRITE,
917 .count = 16,
918 .info = snd_us16x08_mix_info,
919 .get = snd_us16x08_eq_get,
920 .put = snd_us16x08_eq_put,
921 .private_value = SND_US16X08_KCSET(SND_US16X08_NO_BIAS, 1, 0, 0x3F)
922 };
923
924 static const struct snd_kcontrol_new snd_us16x08_eq_mid_width_ctl = {
925 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
926 .access = SNDRV_CTL_ELEM_ACCESS_READWRITE,
927 .count = 16,
928 .info = snd_us16x08_mix_info,
929 .get = snd_us16x08_eq_get,
930 .put = snd_us16x08_eq_put,
931 .private_value = SND_US16X08_KCSET(SND_US16X08_NO_BIAS, 1, 0, 0x06)
932 };
933
934 static const struct snd_kcontrol_new snd_us16x08_eq_high_freq_ctl = {
935 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
936 .access = SNDRV_CTL_ELEM_ACCESS_READWRITE,
937 .count = 16,
938 .info = snd_us16x08_mix_info,
939 .get = snd_us16x08_eq_get,
940 .put = snd_us16x08_eq_put,
941 .private_value =
942 SND_US16X08_KCSET(SND_US16X08_EQ_HIGHFREQ_BIAS, 1, 0, 0x1F)
943 };
944
945 static const struct snd_kcontrol_new snd_us16x08_eq_switch_ctl = {
946 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
947 .access = SNDRV_CTL_ELEM_ACCESS_READWRITE,
948 .count = 16,
949 .info = snd_us16x08_switch_info,
950 .get = snd_us16x08_eqswitch_get,
951 .put = snd_us16x08_eqswitch_put,
952 .private_value = SND_US16X08_KCSET(SND_US16X08_NO_BIAS, 1, 0, 1)
953 };
954
955 static const struct snd_kcontrol_new snd_us16x08_meter_ctl = {
956 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
957 .access = SNDRV_CTL_ELEM_ACCESS_READWRITE,
958 .count = 1,
959 .info = snd_us16x08_meter_info,
960 .get = snd_us16x08_meter_get,
961 .put = snd_us16x08_meter_put
962 };
963
964 /* control store preparation */
965
966 /* setup compressor store and assign default value */
snd_us16x08_create_comp_store(void)967 static struct snd_us16x08_comp_store *snd_us16x08_create_comp_store(void)
968 {
969 int i;
970 struct snd_us16x08_comp_store *tmp;
971
972 tmp = kmalloc(sizeof(*tmp), GFP_KERNEL);
973 if (!tmp)
974 return NULL;
975
976 for (i = 0; i < SND_US16X08_MAX_CHANNELS; i++) {
977 tmp->val[COMP_STORE_IDX(SND_US16X08_ID_COMP_THRESHOLD)][i]
978 = 0x20;
979 tmp->val[COMP_STORE_IDX(SND_US16X08_ID_COMP_RATIO)][i] = 0x00;
980 tmp->val[COMP_STORE_IDX(SND_US16X08_ID_COMP_GAIN)][i] = 0x00;
981 tmp->val[COMP_STORE_IDX(SND_US16X08_ID_COMP_SWITCH)][i] = 0x00;
982 tmp->val[COMP_STORE_IDX(SND_US16X08_ID_COMP_ATTACK)][i] = 0x00;
983 tmp->val[COMP_STORE_IDX(SND_US16X08_ID_COMP_RELEASE)][i] = 0x00;
984 }
985 return tmp;
986 }
987
988 /* setup EQ store and assign default values */
snd_us16x08_create_eq_store(void)989 static struct snd_us16x08_eq_store *snd_us16x08_create_eq_store(void)
990 {
991 int i, b_idx;
992 struct snd_us16x08_eq_store *tmp;
993
994 tmp = kmalloc(sizeof(*tmp), GFP_KERNEL);
995 if (!tmp)
996 return NULL;
997
998 for (i = 0; i < SND_US16X08_MAX_CHANNELS; i++) {
999 for (b_idx = 0; b_idx < SND_US16X08_ID_EQ_BAND_COUNT; b_idx++) {
1000 tmp->val[b_idx][0][i] = 0x0c;
1001 tmp->val[b_idx][3][i] = 0x00;
1002 switch (b_idx) {
1003 case 0: /* EQ Low */
1004 tmp->val[b_idx][1][i] = 0x05;
1005 tmp->val[b_idx][2][i] = 0xff;
1006 break;
1007 case 1: /* EQ Mid low */
1008 tmp->val[b_idx][1][i] = 0x0e;
1009 tmp->val[b_idx][2][i] = 0x02;
1010 break;
1011 case 2: /* EQ Mid High */
1012 tmp->val[b_idx][1][i] = 0x1b;
1013 tmp->val[b_idx][2][i] = 0x02;
1014 break;
1015 case 3: /* EQ High */
1016 tmp->val[b_idx][1][i] = 0x2f
1017 - SND_US16X08_EQ_HIGHFREQ_BIAS;
1018 tmp->val[b_idx][2][i] = 0xff;
1019 break;
1020 }
1021 }
1022 }
1023 return tmp;
1024 }
1025
snd_us16x08_create_meter_store(void)1026 static struct snd_us16x08_meter_store *snd_us16x08_create_meter_store(void)
1027 {
1028 struct snd_us16x08_meter_store *tmp;
1029
1030 tmp = kzalloc(sizeof(*tmp), GFP_KERNEL);
1031 if (!tmp)
1032 return NULL;
1033 tmp->comp_index = 1;
1034 tmp->comp_active_index = 0;
1035 return tmp;
1036 }
1037
1038 /* release elem->private_free as well; called only once for each *_store */
elem_private_free(struct snd_kcontrol * kctl)1039 static void elem_private_free(struct snd_kcontrol *kctl)
1040 {
1041 struct usb_mixer_elem_info *elem = kctl->private_data;
1042
1043 if (elem)
1044 kfree(elem->private_data);
1045 kfree(elem);
1046 kctl->private_data = NULL;
1047 }
1048
add_new_ctl(struct usb_mixer_interface * mixer,const struct snd_kcontrol_new * ncontrol,int index,int val_type,int channels,const char * name,void * opt,bool do_private_free,struct usb_mixer_elem_info ** elem_ret)1049 static int add_new_ctl(struct usb_mixer_interface *mixer,
1050 const struct snd_kcontrol_new *ncontrol,
1051 int index, int val_type, int channels,
1052 const char *name, void *opt,
1053 bool do_private_free,
1054 struct usb_mixer_elem_info **elem_ret)
1055 {
1056 struct snd_kcontrol *kctl;
1057 struct usb_mixer_elem_info *elem;
1058 int err;
1059
1060 usb_audio_dbg(mixer->chip, "us16x08 add mixer %s\n", name);
1061
1062 elem = kzalloc(sizeof(*elem), GFP_KERNEL);
1063 if (!elem)
1064 return -ENOMEM;
1065
1066 elem->head.mixer = mixer;
1067 elem->head.resume = NULL;
1068 elem->control = 0;
1069 elem->idx_off = 0;
1070 elem->head.id = index;
1071 elem->val_type = val_type;
1072 elem->channels = channels;
1073 elem->private_data = opt;
1074
1075 kctl = snd_ctl_new1(ncontrol, elem);
1076 if (!kctl) {
1077 kfree(elem);
1078 return -ENOMEM;
1079 }
1080
1081 if (do_private_free)
1082 kctl->private_free = elem_private_free;
1083 else
1084 kctl->private_free = snd_usb_mixer_elem_free;
1085
1086 strscpy(kctl->id.name, name, sizeof(kctl->id.name));
1087
1088 err = snd_usb_mixer_add_control(&elem->head, kctl);
1089 if (err < 0)
1090 return err;
1091
1092 if (elem_ret)
1093 *elem_ret = elem;
1094
1095 return 0;
1096 }
1097
1098 /* table of EQ controls */
1099 static const struct snd_us16x08_control_params eq_controls[] = {
1100 { /* EQ switch */
1101 .kcontrol_new = &snd_us16x08_eq_switch_ctl,
1102 .control_id = SND_US16X08_ID_EQENABLE,
1103 .type = USB_MIXER_BOOLEAN,
1104 .num_channels = 16,
1105 .name = "EQ Switch",
1106 },
1107 { /* EQ low gain */
1108 .kcontrol_new = &snd_us16x08_eq_gain_ctl,
1109 .control_id = SND_US16X08_ID_EQLOWLEVEL,
1110 .type = USB_MIXER_U8,
1111 .num_channels = 16,
1112 .name = "EQ Low Volume",
1113 },
1114 { /* EQ low freq */
1115 .kcontrol_new = &snd_us16x08_eq_low_freq_ctl,
1116 .control_id = SND_US16X08_ID_EQLOWFREQ,
1117 .type = USB_MIXER_U8,
1118 .num_channels = 16,
1119 .name = "EQ Low Frequency",
1120 },
1121 { /* EQ mid low gain */
1122 .kcontrol_new = &snd_us16x08_eq_gain_ctl,
1123 .control_id = SND_US16X08_ID_EQLOWMIDLEVEL,
1124 .type = USB_MIXER_U8,
1125 .num_channels = 16,
1126 .name = "EQ MidLow Volume",
1127 },
1128 { /* EQ mid low freq */
1129 .kcontrol_new = &snd_us16x08_eq_mid_freq_ctl,
1130 .control_id = SND_US16X08_ID_EQLOWMIDFREQ,
1131 .type = USB_MIXER_U8,
1132 .num_channels = 16,
1133 .name = "EQ MidLow Frequency",
1134 },
1135 { /* EQ mid low Q */
1136 .kcontrol_new = &snd_us16x08_eq_mid_width_ctl,
1137 .control_id = SND_US16X08_ID_EQLOWMIDWIDTH,
1138 .type = USB_MIXER_U8,
1139 .num_channels = 16,
1140 .name = "EQ MidLow Q",
1141 },
1142 { /* EQ mid high gain */
1143 .kcontrol_new = &snd_us16x08_eq_gain_ctl,
1144 .control_id = SND_US16X08_ID_EQHIGHMIDLEVEL,
1145 .type = USB_MIXER_U8,
1146 .num_channels = 16,
1147 .name = "EQ MidHigh Volume",
1148 },
1149 { /* EQ mid high freq */
1150 .kcontrol_new = &snd_us16x08_eq_mid_freq_ctl,
1151 .control_id = SND_US16X08_ID_EQHIGHMIDFREQ,
1152 .type = USB_MIXER_U8,
1153 .num_channels = 16,
1154 .name = "EQ MidHigh Frequency",
1155 },
1156 { /* EQ mid high Q */
1157 .kcontrol_new = &snd_us16x08_eq_mid_width_ctl,
1158 .control_id = SND_US16X08_ID_EQHIGHMIDWIDTH,
1159 .type = USB_MIXER_U8,
1160 .num_channels = 16,
1161 .name = "EQ MidHigh Q",
1162 },
1163 { /* EQ high gain */
1164 .kcontrol_new = &snd_us16x08_eq_gain_ctl,
1165 .control_id = SND_US16X08_ID_EQHIGHLEVEL,
1166 .type = USB_MIXER_U8,
1167 .num_channels = 16,
1168 .name = "EQ High Volume",
1169 },
1170 { /* EQ low freq */
1171 .kcontrol_new = &snd_us16x08_eq_high_freq_ctl,
1172 .control_id = SND_US16X08_ID_EQHIGHFREQ,
1173 .type = USB_MIXER_U8,
1174 .num_channels = 16,
1175 .name = "EQ High Frequency",
1176 },
1177 };
1178
1179 /* table of compressor controls */
1180 static const struct snd_us16x08_control_params comp_controls[] = {
1181 { /* Comp enable */
1182 .kcontrol_new = &snd_us16x08_compswitch_ctl,
1183 .control_id = SND_US16X08_ID_COMP_SWITCH,
1184 .type = USB_MIXER_BOOLEAN,
1185 .num_channels = 16,
1186 .name = "Compressor Switch",
1187 },
1188 { /* Comp threshold */
1189 .kcontrol_new = &snd_us16x08_comp_threshold_ctl,
1190 .control_id = SND_US16X08_ID_COMP_THRESHOLD,
1191 .type = USB_MIXER_U8,
1192 .num_channels = 16,
1193 .name = "Compressor Threshold Volume",
1194 },
1195 { /* Comp ratio */
1196 .kcontrol_new = &snd_us16x08_comp_ratio_ctl,
1197 .control_id = SND_US16X08_ID_COMP_RATIO,
1198 .type = USB_MIXER_U8,
1199 .num_channels = 16,
1200 .name = "Compressor Ratio",
1201 },
1202 { /* Comp attack */
1203 .kcontrol_new = &snd_us16x08_comp_attack_ctl,
1204 .control_id = SND_US16X08_ID_COMP_ATTACK,
1205 .type = USB_MIXER_U8,
1206 .num_channels = 16,
1207 .name = "Compressor Attack",
1208 },
1209 { /* Comp release */
1210 .kcontrol_new = &snd_us16x08_comp_release_ctl,
1211 .control_id = SND_US16X08_ID_COMP_RELEASE,
1212 .type = USB_MIXER_U8,
1213 .num_channels = 16,
1214 .name = "Compressor Release",
1215 },
1216 { /* Comp gain */
1217 .kcontrol_new = &snd_us16x08_comp_gain_ctl,
1218 .control_id = SND_US16X08_ID_COMP_GAIN,
1219 .type = USB_MIXER_U8,
1220 .num_channels = 16,
1221 .name = "Compressor Volume",
1222 },
1223 };
1224
1225 /* table of channel controls */
1226 static const struct snd_us16x08_control_params channel_controls[] = {
1227 { /* Phase */
1228 .kcontrol_new = &snd_us16x08_ch_boolean_ctl,
1229 .control_id = SND_US16X08_ID_PHASE,
1230 .type = USB_MIXER_BOOLEAN,
1231 .num_channels = 16,
1232 .name = "Phase Switch",
1233 .default_val = 0
1234 },
1235 { /* Fader */
1236 .kcontrol_new = &snd_us16x08_ch_int_ctl,
1237 .control_id = SND_US16X08_ID_FADER,
1238 .type = USB_MIXER_U8,
1239 .num_channels = 16,
1240 .name = "Line Volume",
1241 .default_val = 127
1242 },
1243 { /* Mute */
1244 .kcontrol_new = &snd_us16x08_ch_boolean_ctl,
1245 .control_id = SND_US16X08_ID_MUTE,
1246 .type = USB_MIXER_BOOLEAN,
1247 .num_channels = 16,
1248 .name = "Mute Switch",
1249 .default_val = 0
1250 },
1251 { /* Pan */
1252 .kcontrol_new = &snd_us16x08_pan_int_ctl,
1253 .control_id = SND_US16X08_ID_PAN,
1254 .type = USB_MIXER_U16,
1255 .num_channels = 16,
1256 .name = "Pan Left-Right Volume",
1257 .default_val = 127
1258 },
1259 };
1260
1261 /* table of master controls */
1262 static const struct snd_us16x08_control_params master_controls[] = {
1263 { /* Master */
1264 .kcontrol_new = &snd_us16x08_master_ctl,
1265 .control_id = SND_US16X08_ID_FADER,
1266 .type = USB_MIXER_U8,
1267 .num_channels = 16,
1268 .name = "Master Volume",
1269 .default_val = 127
1270 },
1271 { /* Bypass */
1272 .kcontrol_new = &snd_us16x08_bus_ctl,
1273 .control_id = SND_US16X08_ID_BYPASS,
1274 .type = USB_MIXER_BOOLEAN,
1275 .num_channels = 16,
1276 .name = "DSP Bypass Switch",
1277 .default_val = 0
1278 },
1279 { /* Buss out */
1280 .kcontrol_new = &snd_us16x08_bus_ctl,
1281 .control_id = SND_US16X08_ID_BUSS_OUT,
1282 .type = USB_MIXER_BOOLEAN,
1283 .num_channels = 16,
1284 .name = "Buss Out Switch",
1285 .default_val = 0
1286 },
1287 { /* Master mute */
1288 .kcontrol_new = &snd_us16x08_bus_ctl,
1289 .control_id = SND_US16X08_ID_MUTE,
1290 .type = USB_MIXER_BOOLEAN,
1291 .num_channels = 16,
1292 .name = "Master Mute Switch",
1293 .default_val = 0
1294 },
1295
1296 };
1297
snd_us16x08_controls_create(struct usb_mixer_interface * mixer)1298 int snd_us16x08_controls_create(struct usb_mixer_interface *mixer)
1299 {
1300 int i, j;
1301 int err;
1302 struct usb_mixer_elem_info *elem;
1303 struct snd_us16x08_comp_store *comp_store;
1304 struct snd_us16x08_meter_store *meter_store;
1305 struct snd_us16x08_eq_store *eq_store;
1306
1307 /* just check for non-MIDI interface */
1308 if (mixer->hostif->desc.bInterfaceNumber == 3) {
1309
1310 /* add routing control */
1311 err = add_new_ctl(mixer, &snd_us16x08_route_ctl,
1312 SND_US16X08_ID_ROUTE, USB_MIXER_U8, 8, "Line Out Route",
1313 NULL, false, &elem);
1314 if (err < 0) {
1315 usb_audio_dbg(mixer->chip,
1316 "Failed to create route control, err:%d\n",
1317 err);
1318 return err;
1319 }
1320 for (i = 0; i < 8; i++)
1321 elem->cache_val[i] = i < 2 ? i : i + 2;
1322 elem->cached = 0xff;
1323
1324 /* create compressor mixer elements */
1325 comp_store = snd_us16x08_create_comp_store();
1326 if (!comp_store)
1327 return -ENOMEM;
1328
1329 /* add master controls */
1330 for (i = 0; i < ARRAY_SIZE(master_controls); i++) {
1331
1332 err = add_new_ctl(mixer,
1333 master_controls[i].kcontrol_new,
1334 master_controls[i].control_id,
1335 master_controls[i].type,
1336 master_controls[i].num_channels,
1337 master_controls[i].name,
1338 comp_store,
1339 i == 0, /* release comp_store only once */
1340 &elem);
1341 if (err < 0)
1342 return err;
1343 elem->cache_val[0] = master_controls[i].default_val;
1344 elem->cached = 1;
1345 }
1346
1347 /* add channel controls */
1348 for (i = 0; i < ARRAY_SIZE(channel_controls); i++) {
1349
1350 err = add_new_ctl(mixer,
1351 channel_controls[i].kcontrol_new,
1352 channel_controls[i].control_id,
1353 channel_controls[i].type,
1354 channel_controls[i].num_channels,
1355 channel_controls[i].name,
1356 comp_store,
1357 false, &elem);
1358 if (err < 0)
1359 return err;
1360 for (j = 0; j < SND_US16X08_MAX_CHANNELS; j++) {
1361 elem->cache_val[j] =
1362 channel_controls[i].default_val;
1363 }
1364 elem->cached = 0xffff;
1365 }
1366
1367 /* create eq store */
1368 eq_store = snd_us16x08_create_eq_store();
1369 if (!eq_store)
1370 return -ENOMEM;
1371
1372 /* add EQ controls */
1373 for (i = 0; i < ARRAY_SIZE(eq_controls); i++) {
1374
1375 err = add_new_ctl(mixer,
1376 eq_controls[i].kcontrol_new,
1377 eq_controls[i].control_id,
1378 eq_controls[i].type,
1379 eq_controls[i].num_channels,
1380 eq_controls[i].name,
1381 eq_store,
1382 i == 0, /* release eq_store only once */
1383 NULL);
1384 if (err < 0)
1385 return err;
1386 }
1387
1388 /* add compressor controls */
1389 for (i = 0; i < ARRAY_SIZE(comp_controls); i++) {
1390
1391 err = add_new_ctl(mixer,
1392 comp_controls[i].kcontrol_new,
1393 comp_controls[i].control_id,
1394 comp_controls[i].type,
1395 comp_controls[i].num_channels,
1396 comp_controls[i].name,
1397 comp_store,
1398 false, NULL);
1399 if (err < 0)
1400 return err;
1401 }
1402
1403 /* create meters store */
1404 meter_store = snd_us16x08_create_meter_store();
1405 if (!meter_store)
1406 return -ENOMEM;
1407
1408 /* meter function 'get' must access to compressor store
1409 * so place a reference here
1410 */
1411 meter_store->comp_store = comp_store;
1412 err = add_new_ctl(mixer, &snd_us16x08_meter_ctl,
1413 SND_US16X08_ID_METER, USB_MIXER_U16, 0, "Level Meter",
1414 meter_store, true, NULL);
1415 if (err < 0)
1416 return err;
1417 }
1418
1419 return 0;
1420 }
1421
1422