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