xref: /linux/sound/usb/mixer_us16x08.c (revision 05a54fa773284d1a7923cdfdd8f0c8dabb98bd26)
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 
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  */
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 
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 
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 
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 
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 
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 
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 
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 
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 */
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 
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 
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 
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 
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 
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 
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 
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 
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 
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 */
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 */
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 
659 	if (MUA0(meter_urb, s) == 0x61 && MUA1(meter_urb, s) == 0x02 &&
660 		MUA2(meter_urb, s) == 0x04 && MUB0(meter_urb, s) == 0x62) {
661 		if (MUC0(meter_urb, s) == 0x72)
662 			store->meter_level[MUB2(meter_urb, s) - 1] = val;
663 		if (MUC0(meter_urb, s) == 0xb2)
664 			store->comp_level[MUB2(meter_urb, s) - 1] = val;
665 	}
666 	if (MUA0(meter_urb, s) == 0x61 && MUA1(meter_urb, s) == 0x02 &&
667 		MUA2(meter_urb, s) == 0x02 && MUB0(meter_urb, s) == 0x62)
668 		store->master_level[MUB2(meter_urb, s) - 1] = val;
669 }
670 
671 /* Function to retrieve current meter values from the device.
672  *
673  * The device needs to be polled for meter values with an initial
674  * requests. It will return with a sequence of different meter value
675  * packages. The first request (case 0:) initiate this meter response sequence.
676  * After the third response, an additional request can be placed,
677  * to retrieve compressor reduction level value for given channel. This round
678  * trip channel selector will skip all inactive compressors.
679  * A mixer can interrupt this round-trip by selecting one ore two (stereo-link)
680  * specific channels.
681  */
682 static int snd_us16x08_meter_get(struct snd_kcontrol *kcontrol,
683 	struct snd_ctl_elem_value *ucontrol)
684 {
685 	int i, set;
686 	struct usb_mixer_elem_info *elem = snd_kcontrol_chip(kcontrol);
687 	struct snd_usb_audio *chip = elem->head.mixer->chip;
688 	struct snd_us16x08_meter_store *store = elem->private_data;
689 	u8 meter_urb[64] = {0};
690 
691 	switch (kcontrol->private_value) {
692 	case 0: {
693 		char tmp[sizeof(mix_init_msg1)];
694 
695 		memcpy(tmp, mix_init_msg1, sizeof(mix_init_msg1));
696 		snd_us16x08_send_urb(chip, tmp, 4);
697 		snd_us16x08_recv_urb(chip, meter_urb,
698 			sizeof(meter_urb));
699 		kcontrol->private_value++;
700 		break;
701 	}
702 	case 1:
703 		snd_us16x08_recv_urb(chip, meter_urb,
704 			sizeof(meter_urb));
705 		kcontrol->private_value++;
706 		break;
707 	case 2:
708 		snd_us16x08_recv_urb(chip, meter_urb,
709 			sizeof(meter_urb));
710 		kcontrol->private_value++;
711 		break;
712 	case 3: {
713 		char tmp[sizeof(mix_init_msg2)];
714 
715 		memcpy(tmp, mix_init_msg2, sizeof(mix_init_msg2));
716 		tmp[2] = snd_get_meter_comp_index(store);
717 		snd_us16x08_send_urb(chip, tmp, 10);
718 		snd_us16x08_recv_urb(chip, meter_urb,
719 			sizeof(meter_urb));
720 		kcontrol->private_value = 0;
721 		break;
722 	}
723 	}
724 
725 	for (set = 0; set < 6; set++)
726 		get_meter_levels_from_urb(set, store, meter_urb);
727 
728 	for (i = 0; i < SND_US16X08_MAX_CHANNELS; i++) {
729 		ucontrol->value.integer.value[i] =
730 			store ? store->meter_level[i] : 0;
731 	}
732 
733 	ucontrol->value.integer.value[i++] = store ? store->master_level[0] : 0;
734 	ucontrol->value.integer.value[i++] = store ? store->master_level[1] : 0;
735 
736 	for (i = 2; i < SND_US16X08_MAX_CHANNELS + 2; i++)
737 		ucontrol->value.integer.value[i + SND_US16X08_MAX_CHANNELS] =
738 		store ? store->comp_level[i - 2] : 0;
739 
740 	return 1;
741 }
742 
743 static int snd_us16x08_meter_put(struct snd_kcontrol *kcontrol,
744 	struct snd_ctl_elem_value *ucontrol)
745 {
746 	struct usb_mixer_elem_info *elem = snd_kcontrol_chip(kcontrol);
747 	struct snd_us16x08_meter_store *store = elem->private_data;
748 	int val;
749 
750 	val = ucontrol->value.integer.value[0];
751 
752 	/* sanity check */
753 	if (val < 0 || val >= SND_US16X08_MAX_CHANNELS)
754 		return -EINVAL;
755 
756 	store->comp_active_index = val;
757 	store->comp_index = val;
758 
759 	return 1;
760 }
761 
762 static const struct snd_kcontrol_new snd_us16x08_ch_boolean_ctl = {
763 	.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
764 	.access = SNDRV_CTL_ELEM_ACCESS_READWRITE,
765 	.count = 16,
766 	.info = snd_us16x08_switch_info,
767 	.get = snd_us16x08_channel_get,
768 	.put = snd_us16x08_channel_put,
769 	.private_value = SND_US16X08_KCSET(SND_US16X08_NO_BIAS, 1, 0, 1)
770 };
771 
772 static const struct snd_kcontrol_new snd_us16x08_ch_int_ctl = {
773 	.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
774 	.access = SNDRV_CTL_ELEM_ACCESS_READWRITE,
775 	.count = 16,
776 	.info = snd_us16x08_mix_info,
777 	.get = snd_us16x08_channel_get,
778 	.put = snd_us16x08_channel_put,
779 	.private_value = SND_US16X08_KCSET(SND_US16X08_FADER_BIAS, 1, 0, 133)
780 };
781 
782 static const struct snd_kcontrol_new snd_us16x08_pan_int_ctl = {
783 	.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
784 	.access = SNDRV_CTL_ELEM_ACCESS_READWRITE,
785 	.count = 16,
786 	.info = snd_us16x08_mix_info,
787 	.get = snd_us16x08_channel_get,
788 	.put = snd_us16x08_channel_put,
789 	.private_value = SND_US16X08_KCSET(SND_US16X08_FADER_BIAS, 1, 0, 255)
790 };
791 
792 static const struct snd_kcontrol_new snd_us16x08_master_ctl = {
793 	.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
794 	.access = SNDRV_CTL_ELEM_ACCESS_READWRITE,
795 	.count = 1,
796 	.info = snd_us16x08_master_info,
797 	.get = snd_us16x08_master_get,
798 	.put = snd_us16x08_master_put,
799 	.private_value = SND_US16X08_KCSET(SND_US16X08_FADER_BIAS, 1, 0, 133)
800 };
801 
802 static const struct snd_kcontrol_new snd_us16x08_route_ctl = {
803 	.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
804 	.access = SNDRV_CTL_ELEM_ACCESS_READWRITE,
805 	.count = 8,
806 	.info = snd_us16x08_route_info,
807 	.get = snd_us16x08_route_get,
808 	.put = snd_us16x08_route_put,
809 	.private_value = SND_US16X08_KCSET(SND_US16X08_NO_BIAS, 1, 0, 9)
810 };
811 
812 static const struct snd_kcontrol_new snd_us16x08_bus_ctl = {
813 	.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
814 	.access = SNDRV_CTL_ELEM_ACCESS_READWRITE,
815 	.count = 1,
816 	.info = snd_us16x08_switch_info,
817 	.get = snd_us16x08_bus_get,
818 	.put = snd_us16x08_bus_put,
819 	.private_value = SND_US16X08_KCSET(SND_US16X08_NO_BIAS, 1, 0, 1)
820 };
821 
822 static const struct snd_kcontrol_new snd_us16x08_compswitch_ctl = {
823 	.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
824 	.access = SNDRV_CTL_ELEM_ACCESS_READWRITE,
825 	.count = 16,
826 	.info = snd_us16x08_switch_info,
827 	.get = snd_us16x08_comp_get,
828 	.put = snd_us16x08_comp_put,
829 	.private_value = SND_US16X08_KCSET(SND_US16X08_NO_BIAS, 1, 0, 1)
830 };
831 
832 static const struct snd_kcontrol_new snd_us16x08_comp_threshold_ctl = {
833 	.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
834 	.access = SNDRV_CTL_ELEM_ACCESS_READWRITE,
835 	.count = 16,
836 	.info = snd_us16x08_mix_info,
837 	.get = snd_us16x08_comp_get,
838 	.put = snd_us16x08_comp_put,
839 	.private_value = SND_US16X08_KCSET(SND_US16X08_COMP_THRESHOLD_BIAS, 1,
840 	0, 0x20)
841 };
842 
843 static const struct snd_kcontrol_new snd_us16x08_comp_ratio_ctl = {
844 	.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
845 	.access = SNDRV_CTL_ELEM_ACCESS_READWRITE,
846 	.count = 16,
847 	.info = snd_us16x08_mix_info,
848 	.get = snd_us16x08_comp_get,
849 	.put = snd_us16x08_comp_put,
850 	.private_value = SND_US16X08_KCSET(SND_US16X08_NO_BIAS, 1, 0,
851 	sizeof(ratio_map) - 1), /*max*/
852 };
853 
854 static const struct snd_kcontrol_new snd_us16x08_comp_gain_ctl = {
855 	.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
856 	.access = SNDRV_CTL_ELEM_ACCESS_READWRITE,
857 	.count = 16,
858 	.info = snd_us16x08_mix_info,
859 	.get = snd_us16x08_comp_get,
860 	.put = snd_us16x08_comp_put,
861 	.private_value = SND_US16X08_KCSET(SND_US16X08_NO_BIAS, 1, 0, 0x14)
862 };
863 
864 static const struct snd_kcontrol_new snd_us16x08_comp_attack_ctl = {
865 	.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
866 	.access = SNDRV_CTL_ELEM_ACCESS_READWRITE,
867 	.count = 16,
868 	.info = snd_us16x08_mix_info,
869 	.get = snd_us16x08_comp_get,
870 	.put = snd_us16x08_comp_put,
871 	.private_value =
872 	SND_US16X08_KCSET(SND_US16X08_COMP_ATTACK_BIAS, 1, 0, 0xc6),
873 };
874 
875 static const struct snd_kcontrol_new snd_us16x08_comp_release_ctl = {
876 	.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
877 	.access = SNDRV_CTL_ELEM_ACCESS_READWRITE,
878 	.count = 16,
879 	.info = snd_us16x08_mix_info,
880 	.get = snd_us16x08_comp_get,
881 	.put = snd_us16x08_comp_put,
882 	.private_value =
883 	SND_US16X08_KCSET(SND_US16X08_COMP_RELEASE_BIAS, 1, 0, 0x63),
884 };
885 
886 static const struct snd_kcontrol_new snd_us16x08_eq_gain_ctl = {
887 	.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
888 	.access = SNDRV_CTL_ELEM_ACCESS_READWRITE,
889 	.count = 16,
890 	.info = snd_us16x08_mix_info,
891 	.get = snd_us16x08_eq_get,
892 	.put = snd_us16x08_eq_put,
893 	.private_value = SND_US16X08_KCSET(SND_US16X08_NO_BIAS, 1, 0, 24),
894 };
895 
896 static const struct snd_kcontrol_new snd_us16x08_eq_low_freq_ctl = {
897 	.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
898 	.access = SNDRV_CTL_ELEM_ACCESS_READWRITE,
899 	.count = 16,
900 	.info = snd_us16x08_mix_info,
901 	.get = snd_us16x08_eq_get,
902 	.put = snd_us16x08_eq_put,
903 	.private_value = SND_US16X08_KCSET(SND_US16X08_NO_BIAS, 1, 0, 0x1F),
904 };
905 
906 static const struct snd_kcontrol_new snd_us16x08_eq_mid_freq_ctl = {
907 	.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
908 	.access = SNDRV_CTL_ELEM_ACCESS_READWRITE,
909 	.count = 16,
910 	.info = snd_us16x08_mix_info,
911 	.get = snd_us16x08_eq_get,
912 	.put = snd_us16x08_eq_put,
913 	.private_value = SND_US16X08_KCSET(SND_US16X08_NO_BIAS, 1, 0, 0x3F)
914 };
915 
916 static const struct snd_kcontrol_new snd_us16x08_eq_mid_width_ctl = {
917 	.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
918 	.access = SNDRV_CTL_ELEM_ACCESS_READWRITE,
919 	.count = 16,
920 	.info = snd_us16x08_mix_info,
921 	.get = snd_us16x08_eq_get,
922 	.put = snd_us16x08_eq_put,
923 	.private_value = SND_US16X08_KCSET(SND_US16X08_NO_BIAS, 1, 0, 0x06)
924 };
925 
926 static const struct snd_kcontrol_new snd_us16x08_eq_high_freq_ctl = {
927 	.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
928 	.access = SNDRV_CTL_ELEM_ACCESS_READWRITE,
929 	.count = 16,
930 	.info = snd_us16x08_mix_info,
931 	.get = snd_us16x08_eq_get,
932 	.put = snd_us16x08_eq_put,
933 	.private_value =
934 	SND_US16X08_KCSET(SND_US16X08_EQ_HIGHFREQ_BIAS, 1, 0, 0x1F)
935 };
936 
937 static const struct snd_kcontrol_new snd_us16x08_eq_switch_ctl = {
938 	.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
939 	.access = SNDRV_CTL_ELEM_ACCESS_READWRITE,
940 	.count = 16,
941 	.info = snd_us16x08_switch_info,
942 	.get = snd_us16x08_eqswitch_get,
943 	.put = snd_us16x08_eqswitch_put,
944 	.private_value = SND_US16X08_KCSET(SND_US16X08_NO_BIAS, 1, 0, 1)
945 };
946 
947 static const struct snd_kcontrol_new snd_us16x08_meter_ctl = {
948 	.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
949 	.access = SNDRV_CTL_ELEM_ACCESS_READWRITE,
950 	.count = 1,
951 	.info = snd_us16x08_meter_info,
952 	.get = snd_us16x08_meter_get,
953 	.put = snd_us16x08_meter_put
954 };
955 
956 /* control store preparation */
957 
958 /* setup compressor store and assign default value */
959 static struct snd_us16x08_comp_store *snd_us16x08_create_comp_store(void)
960 {
961 	int i;
962 	struct snd_us16x08_comp_store *tmp;
963 
964 	tmp = kmalloc(sizeof(*tmp), GFP_KERNEL);
965 	if (!tmp)
966 		return NULL;
967 
968 	for (i = 0; i < SND_US16X08_MAX_CHANNELS; i++) {
969 		tmp->val[COMP_STORE_IDX(SND_US16X08_ID_COMP_THRESHOLD)][i]
970 			= 0x20;
971 		tmp->val[COMP_STORE_IDX(SND_US16X08_ID_COMP_RATIO)][i] = 0x00;
972 		tmp->val[COMP_STORE_IDX(SND_US16X08_ID_COMP_GAIN)][i] = 0x00;
973 		tmp->val[COMP_STORE_IDX(SND_US16X08_ID_COMP_SWITCH)][i] = 0x00;
974 		tmp->val[COMP_STORE_IDX(SND_US16X08_ID_COMP_ATTACK)][i] = 0x00;
975 		tmp->val[COMP_STORE_IDX(SND_US16X08_ID_COMP_RELEASE)][i] = 0x00;
976 	}
977 	return tmp;
978 }
979 
980 /* setup EQ store and assign default values */
981 static struct snd_us16x08_eq_store *snd_us16x08_create_eq_store(void)
982 {
983 	int i, b_idx;
984 	struct snd_us16x08_eq_store *tmp;
985 
986 	tmp = kmalloc(sizeof(*tmp), GFP_KERNEL);
987 	if (!tmp)
988 		return NULL;
989 
990 	for (i = 0; i < SND_US16X08_MAX_CHANNELS; i++) {
991 		for (b_idx = 0; b_idx < SND_US16X08_ID_EQ_BAND_COUNT; b_idx++) {
992 			tmp->val[b_idx][0][i] = 0x0c;
993 			tmp->val[b_idx][3][i] = 0x00;
994 			switch (b_idx) {
995 			case 0: /* EQ Low */
996 				tmp->val[b_idx][1][i] = 0x05;
997 				tmp->val[b_idx][2][i] = 0xff;
998 				break;
999 			case 1: /* EQ Mid low */
1000 				tmp->val[b_idx][1][i] = 0x0e;
1001 				tmp->val[b_idx][2][i] = 0x02;
1002 				break;
1003 			case 2: /* EQ Mid High */
1004 				tmp->val[b_idx][1][i] = 0x1b;
1005 				tmp->val[b_idx][2][i] = 0x02;
1006 				break;
1007 			case 3: /* EQ High */
1008 				tmp->val[b_idx][1][i] = 0x2f
1009 					- SND_US16X08_EQ_HIGHFREQ_BIAS;
1010 				tmp->val[b_idx][2][i] = 0xff;
1011 				break;
1012 			}
1013 		}
1014 	}
1015 	return tmp;
1016 }
1017 
1018 static struct snd_us16x08_meter_store *snd_us16x08_create_meter_store(void)
1019 {
1020 	struct snd_us16x08_meter_store *tmp;
1021 
1022 	tmp = kzalloc(sizeof(*tmp), GFP_KERNEL);
1023 	if (!tmp)
1024 		return NULL;
1025 	tmp->comp_index = 1;
1026 	tmp->comp_active_index = 0;
1027 	return tmp;
1028 }
1029 
1030 /* release elem->private_free as well; called only once for each *_store */
1031 static void elem_private_free(struct snd_kcontrol *kctl)
1032 {
1033 	struct usb_mixer_elem_info *elem = kctl->private_data;
1034 
1035 	if (elem)
1036 		kfree(elem->private_data);
1037 	kfree(elem);
1038 	kctl->private_data = NULL;
1039 }
1040 
1041 static int add_new_ctl(struct usb_mixer_interface *mixer,
1042 	const struct snd_kcontrol_new *ncontrol,
1043 	int index, int val_type, int channels,
1044 	const char *name, void *opt,
1045 	bool do_private_free,
1046 	struct usb_mixer_elem_info **elem_ret)
1047 {
1048 	struct snd_kcontrol *kctl;
1049 	struct usb_mixer_elem_info *elem;
1050 	int err;
1051 
1052 	usb_audio_dbg(mixer->chip, "us16x08 add mixer %s\n", name);
1053 
1054 	elem = kzalloc(sizeof(*elem), GFP_KERNEL);
1055 	if (!elem)
1056 		return -ENOMEM;
1057 
1058 	elem->head.mixer = mixer;
1059 	elem->head.resume = NULL;
1060 	elem->control = 0;
1061 	elem->idx_off = 0;
1062 	elem->head.id = index;
1063 	elem->val_type = val_type;
1064 	elem->channels = channels;
1065 	elem->private_data = opt;
1066 
1067 	kctl = snd_ctl_new1(ncontrol, elem);
1068 	if (!kctl) {
1069 		kfree(elem);
1070 		return -ENOMEM;
1071 	}
1072 
1073 	if (do_private_free)
1074 		kctl->private_free = elem_private_free;
1075 	else
1076 		kctl->private_free = snd_usb_mixer_elem_free;
1077 
1078 	strscpy(kctl->id.name, name, sizeof(kctl->id.name));
1079 
1080 	err = snd_usb_mixer_add_control(&elem->head, kctl);
1081 	if (err < 0)
1082 		return err;
1083 
1084 	if (elem_ret)
1085 		*elem_ret = elem;
1086 
1087 	return 0;
1088 }
1089 
1090 /* table of EQ controls */
1091 static const struct snd_us16x08_control_params eq_controls[] = {
1092 	{ /* EQ switch */
1093 		.kcontrol_new = &snd_us16x08_eq_switch_ctl,
1094 		.control_id = SND_US16X08_ID_EQENABLE,
1095 		.type = USB_MIXER_BOOLEAN,
1096 		.num_channels = 16,
1097 		.name = "EQ Switch",
1098 	},
1099 	{ /* EQ low gain */
1100 		.kcontrol_new = &snd_us16x08_eq_gain_ctl,
1101 		.control_id = SND_US16X08_ID_EQLOWLEVEL,
1102 		.type = USB_MIXER_U8,
1103 		.num_channels = 16,
1104 		.name = "EQ Low Volume",
1105 	},
1106 	{ /* EQ low freq */
1107 		.kcontrol_new = &snd_us16x08_eq_low_freq_ctl,
1108 		.control_id = SND_US16X08_ID_EQLOWFREQ,
1109 		.type = USB_MIXER_U8,
1110 		.num_channels = 16,
1111 		.name = "EQ Low Frequency",
1112 	},
1113 	{ /* EQ mid low gain */
1114 		.kcontrol_new = &snd_us16x08_eq_gain_ctl,
1115 		.control_id = SND_US16X08_ID_EQLOWMIDLEVEL,
1116 		.type = USB_MIXER_U8,
1117 		.num_channels = 16,
1118 		.name = "EQ MidLow Volume",
1119 	},
1120 	{ /* EQ mid low freq */
1121 		.kcontrol_new = &snd_us16x08_eq_mid_freq_ctl,
1122 		.control_id = SND_US16X08_ID_EQLOWMIDFREQ,
1123 		.type = USB_MIXER_U8,
1124 		.num_channels = 16,
1125 		.name = "EQ MidLow Frequency",
1126 	},
1127 	{ /* EQ mid low Q */
1128 		.kcontrol_new = &snd_us16x08_eq_mid_width_ctl,
1129 		.control_id = SND_US16X08_ID_EQLOWMIDWIDTH,
1130 		.type = USB_MIXER_U8,
1131 		.num_channels = 16,
1132 		.name = "EQ MidLow Q",
1133 	},
1134 	{ /* EQ mid high gain */
1135 		.kcontrol_new = &snd_us16x08_eq_gain_ctl,
1136 		.control_id = SND_US16X08_ID_EQHIGHMIDLEVEL,
1137 		.type = USB_MIXER_U8,
1138 		.num_channels = 16,
1139 		.name = "EQ MidHigh Volume",
1140 	},
1141 	{ /* EQ mid high freq */
1142 		.kcontrol_new = &snd_us16x08_eq_mid_freq_ctl,
1143 		.control_id = SND_US16X08_ID_EQHIGHMIDFREQ,
1144 		.type = USB_MIXER_U8,
1145 		.num_channels = 16,
1146 		.name = "EQ MidHigh Frequency",
1147 	},
1148 	{ /* EQ mid high Q */
1149 		.kcontrol_new = &snd_us16x08_eq_mid_width_ctl,
1150 		.control_id = SND_US16X08_ID_EQHIGHMIDWIDTH,
1151 		.type = USB_MIXER_U8,
1152 		.num_channels = 16,
1153 		.name = "EQ MidHigh Q",
1154 	},
1155 	{ /* EQ high gain */
1156 		.kcontrol_new = &snd_us16x08_eq_gain_ctl,
1157 		.control_id = SND_US16X08_ID_EQHIGHLEVEL,
1158 		.type = USB_MIXER_U8,
1159 		.num_channels = 16,
1160 		.name = "EQ High Volume",
1161 	},
1162 	{ /* EQ low freq */
1163 		.kcontrol_new = &snd_us16x08_eq_high_freq_ctl,
1164 		.control_id = SND_US16X08_ID_EQHIGHFREQ,
1165 		.type = USB_MIXER_U8,
1166 		.num_channels = 16,
1167 		.name = "EQ High Frequency",
1168 	},
1169 };
1170 
1171 /* table of compressor controls */
1172 static const struct snd_us16x08_control_params comp_controls[] = {
1173 	{ /* Comp enable */
1174 		.kcontrol_new = &snd_us16x08_compswitch_ctl,
1175 		.control_id = SND_US16X08_ID_COMP_SWITCH,
1176 		.type = USB_MIXER_BOOLEAN,
1177 		.num_channels = 16,
1178 		.name = "Compressor Switch",
1179 	},
1180 	{ /* Comp threshold */
1181 		.kcontrol_new = &snd_us16x08_comp_threshold_ctl,
1182 		.control_id = SND_US16X08_ID_COMP_THRESHOLD,
1183 		.type = USB_MIXER_U8,
1184 		.num_channels = 16,
1185 		.name = "Compressor Threshold Volume",
1186 	},
1187 	{ /* Comp ratio */
1188 		.kcontrol_new = &snd_us16x08_comp_ratio_ctl,
1189 		.control_id = SND_US16X08_ID_COMP_RATIO,
1190 		.type = USB_MIXER_U8,
1191 		.num_channels = 16,
1192 		.name = "Compressor Ratio",
1193 	},
1194 	{ /* Comp attack */
1195 		.kcontrol_new = &snd_us16x08_comp_attack_ctl,
1196 		.control_id = SND_US16X08_ID_COMP_ATTACK,
1197 		.type = USB_MIXER_U8,
1198 		.num_channels = 16,
1199 		.name = "Compressor Attack",
1200 	},
1201 	{ /* Comp release */
1202 		.kcontrol_new = &snd_us16x08_comp_release_ctl,
1203 		.control_id = SND_US16X08_ID_COMP_RELEASE,
1204 		.type = USB_MIXER_U8,
1205 		.num_channels = 16,
1206 		.name = "Compressor Release",
1207 	},
1208 	{ /* Comp gain */
1209 		.kcontrol_new = &snd_us16x08_comp_gain_ctl,
1210 		.control_id = SND_US16X08_ID_COMP_GAIN,
1211 		.type = USB_MIXER_U8,
1212 		.num_channels = 16,
1213 		.name = "Compressor Volume",
1214 	},
1215 };
1216 
1217 /* table of channel controls */
1218 static const struct snd_us16x08_control_params channel_controls[] = {
1219 	{ /* Phase */
1220 		.kcontrol_new = &snd_us16x08_ch_boolean_ctl,
1221 		.control_id = SND_US16X08_ID_PHASE,
1222 		.type = USB_MIXER_BOOLEAN,
1223 		.num_channels = 16,
1224 		.name = "Phase Switch",
1225 		.default_val = 0
1226 	},
1227 	{ /* Fader */
1228 		.kcontrol_new = &snd_us16x08_ch_int_ctl,
1229 		.control_id = SND_US16X08_ID_FADER,
1230 		.type = USB_MIXER_U8,
1231 		.num_channels = 16,
1232 		.name = "Line Volume",
1233 		.default_val = 127
1234 	},
1235 	{ /* Mute */
1236 		.kcontrol_new = &snd_us16x08_ch_boolean_ctl,
1237 		.control_id = SND_US16X08_ID_MUTE,
1238 		.type = USB_MIXER_BOOLEAN,
1239 		.num_channels = 16,
1240 		.name = "Mute Switch",
1241 		.default_val = 0
1242 	},
1243 	{ /* Pan */
1244 		.kcontrol_new = &snd_us16x08_pan_int_ctl,
1245 		.control_id = SND_US16X08_ID_PAN,
1246 		.type = USB_MIXER_U16,
1247 		.num_channels = 16,
1248 		.name = "Pan Left-Right Volume",
1249 		.default_val = 127
1250 	},
1251 };
1252 
1253 /* table of master controls */
1254 static const struct snd_us16x08_control_params master_controls[] = {
1255 	{ /* Master */
1256 		.kcontrol_new = &snd_us16x08_master_ctl,
1257 		.control_id = SND_US16X08_ID_FADER,
1258 		.type = USB_MIXER_U8,
1259 		.num_channels = 16,
1260 		.name = "Master Volume",
1261 		.default_val = 127
1262 	},
1263 	{ /* Bypass */
1264 		.kcontrol_new = &snd_us16x08_bus_ctl,
1265 		.control_id = SND_US16X08_ID_BYPASS,
1266 		.type = USB_MIXER_BOOLEAN,
1267 		.num_channels = 16,
1268 		.name = "DSP Bypass Switch",
1269 		.default_val = 0
1270 	},
1271 	{ /* Buss out */
1272 		.kcontrol_new = &snd_us16x08_bus_ctl,
1273 		.control_id = SND_US16X08_ID_BUSS_OUT,
1274 		.type = USB_MIXER_BOOLEAN,
1275 		.num_channels = 16,
1276 		.name = "Buss Out Switch",
1277 		.default_val = 0
1278 	},
1279 	{ /* Master mute */
1280 		.kcontrol_new = &snd_us16x08_bus_ctl,
1281 		.control_id = SND_US16X08_ID_MUTE,
1282 		.type = USB_MIXER_BOOLEAN,
1283 		.num_channels = 16,
1284 		.name = "Master Mute Switch",
1285 		.default_val = 0
1286 	},
1287 
1288 };
1289 
1290 int snd_us16x08_controls_create(struct usb_mixer_interface *mixer)
1291 {
1292 	int i, j;
1293 	int err;
1294 	struct usb_mixer_elem_info *elem;
1295 	struct snd_us16x08_comp_store *comp_store;
1296 	struct snd_us16x08_meter_store *meter_store;
1297 	struct snd_us16x08_eq_store *eq_store;
1298 
1299 	/* just check for non-MIDI interface */
1300 	if (mixer->hostif->desc.bInterfaceNumber == 3) {
1301 
1302 		/* add routing control */
1303 		err = add_new_ctl(mixer, &snd_us16x08_route_ctl,
1304 			SND_US16X08_ID_ROUTE, USB_MIXER_U8, 8, "Line Out Route",
1305 			NULL, false, &elem);
1306 		if (err < 0) {
1307 			usb_audio_dbg(mixer->chip,
1308 				"Failed to create route control, err:%d\n",
1309 				err);
1310 			return err;
1311 		}
1312 		for (i = 0; i < 8; i++)
1313 			elem->cache_val[i] = i < 2 ? i : i + 2;
1314 		elem->cached = 0xff;
1315 
1316 		/* create compressor mixer elements */
1317 		comp_store = snd_us16x08_create_comp_store();
1318 		if (!comp_store)
1319 			return -ENOMEM;
1320 
1321 		/* add master controls */
1322 		for (i = 0; i < ARRAY_SIZE(master_controls); i++) {
1323 
1324 			err = add_new_ctl(mixer,
1325 				master_controls[i].kcontrol_new,
1326 				master_controls[i].control_id,
1327 				master_controls[i].type,
1328 				master_controls[i].num_channels,
1329 				master_controls[i].name,
1330 				comp_store,
1331 				i == 0, /* release comp_store only once */
1332 				&elem);
1333 			if (err < 0)
1334 				return err;
1335 			elem->cache_val[0] = master_controls[i].default_val;
1336 			elem->cached = 1;
1337 		}
1338 
1339 		/* add channel controls */
1340 		for (i = 0; i < ARRAY_SIZE(channel_controls); i++) {
1341 
1342 			err = add_new_ctl(mixer,
1343 				channel_controls[i].kcontrol_new,
1344 				channel_controls[i].control_id,
1345 				channel_controls[i].type,
1346 				channel_controls[i].num_channels,
1347 				channel_controls[i].name,
1348 				comp_store,
1349 				false, &elem);
1350 			if (err < 0)
1351 				return err;
1352 			for (j = 0; j < SND_US16X08_MAX_CHANNELS; j++) {
1353 				elem->cache_val[j] =
1354 					channel_controls[i].default_val;
1355 			}
1356 			elem->cached = 0xffff;
1357 		}
1358 
1359 		/* create eq store */
1360 		eq_store = snd_us16x08_create_eq_store();
1361 		if (!eq_store)
1362 			return -ENOMEM;
1363 
1364 		/* add EQ controls */
1365 		for (i = 0; i < ARRAY_SIZE(eq_controls); i++) {
1366 
1367 			err = add_new_ctl(mixer,
1368 				eq_controls[i].kcontrol_new,
1369 				eq_controls[i].control_id,
1370 				eq_controls[i].type,
1371 				eq_controls[i].num_channels,
1372 				eq_controls[i].name,
1373 				eq_store,
1374 				i == 0, /* release eq_store only once */
1375 				NULL);
1376 			if (err < 0)
1377 				return err;
1378 		}
1379 
1380 		/* add compressor controls */
1381 		for (i = 0; i < ARRAY_SIZE(comp_controls); i++) {
1382 
1383 			err = add_new_ctl(mixer,
1384 				comp_controls[i].kcontrol_new,
1385 				comp_controls[i].control_id,
1386 				comp_controls[i].type,
1387 				comp_controls[i].num_channels,
1388 				comp_controls[i].name,
1389 				comp_store,
1390 				false, NULL);
1391 			if (err < 0)
1392 				return err;
1393 		}
1394 
1395 		/* create meters store */
1396 		meter_store = snd_us16x08_create_meter_store();
1397 		if (!meter_store)
1398 			return -ENOMEM;
1399 
1400 		/* meter function 'get' must access to compressor store
1401 		 * so place a reference here
1402 		 */
1403 		meter_store->comp_store = comp_store;
1404 		err = add_new_ctl(mixer, &snd_us16x08_meter_ctl,
1405 			SND_US16X08_ID_METER, USB_MIXER_U16, 0, "Level Meter",
1406 			meter_store, true, NULL);
1407 		if (err < 0)
1408 			return err;
1409 	}
1410 
1411 	return 0;
1412 }
1413 
1414