xref: /linux/sound/usb/mixer_us16x08.c (revision a440c17869ecd71da0f295b62868fc742d09a8ba)
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 		usb_audio_dbg(chip, "Failed to set routing, err:%d\n", err);
229 		return err;
230 	}
231 
232 	elem->cached |= 1 << index;
233 	elem->cache_val[index] = val;
234 	return 1;
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 		usb_audio_dbg(chip, "Failed to set master, err:%d\n", err);
288 		return err;
289 	}
290 
291 	elem->cached |= 1 << index;
292 	elem->cache_val[index] = val;
293 	return 1;
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 		usb_audio_dbg(chip, "Failed to set bus parameter, err:%d\n", err);
329 		return err;
330 	}
331 
332 	elem->cached |= 1;
333 	elem->cache_val[0] = val;
334 	return 1;
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 		usb_audio_dbg(chip, "Failed to set channel, err:%d\n", err);
397 		return err;
398 	}
399 
400 	elem->cached |= 1 << index;
401 	elem->cache_val[index] = val;
402 	return 1;
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 threshold, ratio, attack, release, gain, switch_on;
439 	int err;
440 
441 	val = ucontrol->value.integer.value[0];
442 
443 	/* sanity check */
444 	if (val < SND_US16X08_KCMIN(kcontrol)
445 		|| val > SND_US16X08_KCMAX(kcontrol))
446 		return -EINVAL;
447 
448 	/* new control value incl. bias*/
449 	val_idx = elem->head.id - SND_US16X08_ID_COMP_BASE;
450 
451 	threshold = store->val[COMP_STORE_IDX(SND_US16X08_ID_COMP_THRESHOLD)]
452 		[index];
453 	ratio = store->val[COMP_STORE_IDX(SND_US16X08_ID_COMP_RATIO)][index];
454 	attack = store->val[COMP_STORE_IDX(SND_US16X08_ID_COMP_ATTACK)][index];
455 	release = store->val[COMP_STORE_IDX(SND_US16X08_ID_COMP_RELEASE)]
456 		[index];
457 	gain = store->val[COMP_STORE_IDX(SND_US16X08_ID_COMP_GAIN)][index];
458 	switch_on = store->val[COMP_STORE_IDX(SND_US16X08_ID_COMP_SWITCH)]
459 		[index];
460 
461 	switch (val_idx) {
462 	case COMP_STORE_IDX(SND_US16X08_ID_COMP_THRESHOLD):
463 		threshold = val;
464 		break;
465 	case COMP_STORE_IDX(SND_US16X08_ID_COMP_RATIO):
466 		ratio = val;
467 		break;
468 	case COMP_STORE_IDX(SND_US16X08_ID_COMP_ATTACK):
469 		attack = val;
470 		break;
471 	case COMP_STORE_IDX(SND_US16X08_ID_COMP_RELEASE):
472 		release = val;
473 		break;
474 	case COMP_STORE_IDX(SND_US16X08_ID_COMP_GAIN):
475 		gain = val;
476 		break;
477 	case COMP_STORE_IDX(SND_US16X08_ID_COMP_SWITCH):
478 		switch_on = val;
479 		break;
480 	}
481 
482 	/* prepare compressor URB message from template  */
483 	memcpy(buf, comp_msg, sizeof(comp_msg));
484 
485 	/* place comp values in message buffer watch bias! */
486 	buf[8] = threshold - SND_US16X08_COMP_THRESHOLD_BIAS;
487 	buf[11] = ratio_map[ratio];
488 	buf[14] = attack + SND_US16X08_COMP_ATTACK_BIAS;
489 	buf[17] = release + SND_US16X08_COMP_RELEASE_BIAS;
490 	buf[20] = gain;
491 	buf[26] = switch_on;
492 
493 	/* place channel selector in message buffer */
494 	buf[5] = index + 1;
495 
496 	err = snd_us16x08_send_urb(chip, buf, sizeof(comp_msg));
497 
498 	if (err < 0) {
499 		usb_audio_dbg(chip, "Failed to set compressor, err:%d\n", err);
500 		return err;
501 	}
502 
503 	store->val[val_idx][index] = val;
504 	elem->cached |= 1 << index;
505 	elem->cache_val[index] = val;
506 	return 1;
507 }
508 
509 static int snd_us16x08_eqswitch_get(struct snd_kcontrol *kcontrol,
510 	struct snd_ctl_elem_value *ucontrol)
511 {
512 	int val;
513 	struct usb_mixer_elem_info *elem = snd_kcontrol_chip(kcontrol);
514 	struct snd_us16x08_eq_store *store = elem->private_data;
515 	int index = ucontrol->id.index;
516 
517 	/* get low switch from cache is enough, cause all bands are together */
518 	val = store->val[EQ_STORE_BAND_IDX(elem->head.id)]
519 		[EQ_STORE_PARAM_IDX(elem->head.id)][index];
520 	ucontrol->value.integer.value[0] = val;
521 
522 	return 0;
523 }
524 
525 static int snd_us16x08_eqswitch_put(struct snd_kcontrol *kcontrol,
526 	struct snd_ctl_elem_value *ucontrol)
527 {
528 	struct usb_mixer_elem_info *elem = snd_kcontrol_chip(kcontrol);
529 	struct snd_usb_audio *chip = elem->head.mixer->chip;
530 	struct snd_us16x08_eq_store *store = elem->private_data;
531 	int index = ucontrol->id.index;
532 	char buf[sizeof(eqs_msq)];
533 	int val, err = 0;
534 	int b_idx;
535 
536 	/* new control value incl. bias*/
537 	val = ucontrol->value.integer.value[0] + SND_US16X08_KCBIAS(kcontrol);
538 
539 	/* prepare URB message from EQ template */
540 	memcpy(buf, eqs_msq, sizeof(eqs_msq));
541 
542 	/* place channel index in URB message */
543 	buf[5] = index + 1;
544 	for (b_idx = 0; b_idx < SND_US16X08_ID_EQ_BAND_COUNT; b_idx++) {
545 		/* all four EQ bands have to be enabled/disabled in once */
546 		buf[20] = val;
547 		buf[17] = store->val[b_idx][2][index];
548 		buf[14] = store->val[b_idx][1][index];
549 		buf[11] = store->val[b_idx][0][index];
550 		buf[8] = b_idx + 1;
551 		err = snd_us16x08_send_urb(chip, buf, sizeof(eqs_msq));
552 		if (err < 0)
553 			break;
554 		store->val[b_idx][3][index] = val;
555 		msleep(15);
556 	}
557 
558 	if (err < 0) {
559 		usb_audio_dbg(chip, "Failed to set eq switch, err:%d\n", err);
560 		return err;
561 	}
562 
563 	elem->cached |= 1 << index;
564 	elem->cache_val[index] = val;
565 	return 1;
566 }
567 
568 static int snd_us16x08_eq_get(struct snd_kcontrol *kcontrol,
569 	struct snd_ctl_elem_value *ucontrol)
570 {
571 	int val;
572 	struct usb_mixer_elem_info *elem = snd_kcontrol_chip(kcontrol);
573 	struct snd_us16x08_eq_store *store = elem->private_data;
574 	int index = ucontrol->id.index;
575 	int b_idx = EQ_STORE_BAND_IDX(elem->head.id) - 1;
576 	int p_idx = EQ_STORE_PARAM_IDX(elem->head.id);
577 
578 	val = store->val[b_idx][p_idx][index];
579 
580 	ucontrol->value.integer.value[0] = val;
581 
582 	return 0;
583 }
584 
585 static int snd_us16x08_eq_put(struct snd_kcontrol *kcontrol,
586 	struct snd_ctl_elem_value *ucontrol)
587 {
588 	struct usb_mixer_elem_info *elem = snd_kcontrol_chip(kcontrol);
589 	struct snd_usb_audio *chip = elem->head.mixer->chip;
590 	struct snd_us16x08_eq_store *store = elem->private_data;
591 	int index = ucontrol->id.index;
592 	char buf[sizeof(eqs_msq)];
593 	int val, err;
594 	int b_idx = EQ_STORE_BAND_IDX(elem->head.id) - 1;
595 	int p_idx = EQ_STORE_PARAM_IDX(elem->head.id);
596 
597 	val = ucontrol->value.integer.value[0];
598 
599 	/* sanity check */
600 	if (val < SND_US16X08_KCMIN(kcontrol)
601 		|| val > SND_US16X08_KCMAX(kcontrol))
602 		return -EINVAL;
603 
604 	/* copy URB buffer from EQ template */
605 	memcpy(buf, eqs_msq, sizeof(eqs_msq));
606 
607 	buf[20] = p_idx == 3 ? val : store->val[b_idx][3][index];
608 	buf[17] = p_idx == 2 ? val : store->val[b_idx][2][index];
609 	buf[14] = p_idx == 1 ? val : store->val[b_idx][1][index];
610 	buf[11] = p_idx == 0 ? val : store->val[b_idx][0][index];
611 
612 	/* place channel index in URB buffer */
613 	buf[5] = index + 1;
614 
615 	/* place EQ band in URB buffer */
616 	buf[8] = b_idx + 1;
617 
618 	err = snd_us16x08_send_urb(chip, buf, sizeof(eqs_msq));
619 
620 	if (err < 0) {
621 		usb_audio_dbg(chip, "Failed to set eq param, err:%d\n", err);
622 		return err;
623 	}
624 
625 	store->val[b_idx][p_idx][index] = val;
626 	/* store new value in EQ band cache */
627 	elem->cached |= 1 << index;
628 	elem->cache_val[index] = val;
629 	return 1;
630 }
631 
632 static int snd_us16x08_meter_info(struct snd_kcontrol *kcontrol,
633 	struct snd_ctl_elem_info *uinfo)
634 {
635 	uinfo->count = 34;
636 	uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
637 	uinfo->value.integer.max = 0x7FFF;
638 	uinfo->value.integer.min = 0;
639 
640 	return 0;
641 }
642 
643 /* calculate compressor index for reduction level request */
644 static int snd_get_meter_comp_index(struct snd_us16x08_meter_store *store)
645 {
646 	int ret;
647 
648 	/* any channel active */
649 	if (store->comp_active_index) {
650 		/* check for stereo link */
651 		if (store->comp_active_index & 0x20) {
652 			/* reset comp_index to left channel*/
653 			if (store->comp_index -
654 				store->comp_active_index > 1)
655 				store->comp_index =
656 				store->comp_active_index;
657 
658 			ret = store->comp_index++ & 0x1F;
659 		} else {
660 			/* no stereo link */
661 			ret = store->comp_active_index;
662 		}
663 	} else {
664 		/* skip channels with no compressor active */
665 		while (store->comp_index <= SND_US16X08_MAX_CHANNELS
666 			&& !store->comp_store->val[
667 			COMP_STORE_IDX(SND_US16X08_ID_COMP_SWITCH)]
668 			[store->comp_index - 1]) {
669 			store->comp_index++;
670 		}
671 		ret = store->comp_index++;
672 		if (store->comp_index > SND_US16X08_MAX_CHANNELS)
673 			store->comp_index = 1;
674 	}
675 	return ret;
676 }
677 
678 /* retrieve the meter level values from URB message */
679 static void get_meter_levels_from_urb(int s,
680 	struct snd_us16x08_meter_store *store,
681 	u8 *meter_urb)
682 {
683 	int val = MUC2(meter_urb, s) + (MUC3(meter_urb, s) << 8);
684 	int ch = MUB2(meter_urb, s) - 1;
685 
686 	if (ch < 0)
687 		return;
688 
689 	if (MUA0(meter_urb, s) == 0x61 && MUA1(meter_urb, s) == 0x02 &&
690 		MUA2(meter_urb, s) == 0x04 && MUB0(meter_urb, s) == 0x62) {
691 		if (ch < SND_US16X08_MAX_CHANNELS) {
692 			if (MUC0(meter_urb, s) == 0x72)
693 				store->meter_level[ch] = val;
694 			if (MUC0(meter_urb, s) == 0xb2)
695 				store->comp_level[ch] = val;
696 		}
697 	}
698 	if (MUA0(meter_urb, s) == 0x61 && MUA1(meter_urb, s) == 0x02 &&
699 		MUA2(meter_urb, s) == 0x02 && MUB0(meter_urb, s) == 0x62) {
700 		if (ch < ARRAY_SIZE(store->master_level))
701 			store->master_level[ch] = val;
702 	}
703 }
704 
705 /* Function to retrieve current meter values from the device.
706  *
707  * The device needs to be polled for meter values with an initial
708  * requests. It will return with a sequence of different meter value
709  * packages. The first request (case 0:) initiate this meter response sequence.
710  * After the third response, an additional request can be placed,
711  * to retrieve compressor reduction level value for given channel. This round
712  * trip channel selector will skip all inactive compressors.
713  * A mixer can interrupt this round-trip by selecting one ore two (stereo-link)
714  * specific channels.
715  */
716 static int snd_us16x08_meter_get(struct snd_kcontrol *kcontrol,
717 	struct snd_ctl_elem_value *ucontrol)
718 {
719 	int i, set;
720 	struct usb_mixer_elem_info *elem = snd_kcontrol_chip(kcontrol);
721 	struct snd_usb_audio *chip = elem->head.mixer->chip;
722 	struct snd_us16x08_meter_store *store = elem->private_data;
723 	u8 meter_urb[64] = {0};
724 
725 	switch (kcontrol->private_value) {
726 	case 0: {
727 		char tmp[sizeof(mix_init_msg1)];
728 
729 		memcpy(tmp, mix_init_msg1, sizeof(mix_init_msg1));
730 		snd_us16x08_send_urb(chip, tmp, 4);
731 		snd_us16x08_recv_urb(chip, meter_urb,
732 			sizeof(meter_urb));
733 		kcontrol->private_value++;
734 		break;
735 	}
736 	case 1:
737 		snd_us16x08_recv_urb(chip, meter_urb,
738 			sizeof(meter_urb));
739 		kcontrol->private_value++;
740 		break;
741 	case 2:
742 		snd_us16x08_recv_urb(chip, meter_urb,
743 			sizeof(meter_urb));
744 		kcontrol->private_value++;
745 		break;
746 	case 3: {
747 		char tmp[sizeof(mix_init_msg2)];
748 
749 		memcpy(tmp, mix_init_msg2, sizeof(mix_init_msg2));
750 		tmp[2] = snd_get_meter_comp_index(store);
751 		snd_us16x08_send_urb(chip, tmp, 10);
752 		snd_us16x08_recv_urb(chip, meter_urb,
753 			sizeof(meter_urb));
754 		kcontrol->private_value = 0;
755 		break;
756 	}
757 	}
758 
759 	for (set = 0; set < 6; set++)
760 		get_meter_levels_from_urb(set, store, meter_urb);
761 
762 	for (i = 0; i < SND_US16X08_MAX_CHANNELS; i++) {
763 		ucontrol->value.integer.value[i] =
764 			store ? store->meter_level[i] : 0;
765 	}
766 
767 	ucontrol->value.integer.value[i++] = store ? store->master_level[0] : 0;
768 	ucontrol->value.integer.value[i++] = store ? store->master_level[1] : 0;
769 
770 	for (i = 2; i < SND_US16X08_MAX_CHANNELS + 2; i++)
771 		ucontrol->value.integer.value[i + SND_US16X08_MAX_CHANNELS] =
772 		store ? store->comp_level[i - 2] : 0;
773 
774 	return 1;
775 }
776 
777 static int snd_us16x08_meter_put(struct snd_kcontrol *kcontrol,
778 	struct snd_ctl_elem_value *ucontrol)
779 {
780 	struct usb_mixer_elem_info *elem = snd_kcontrol_chip(kcontrol);
781 	struct snd_us16x08_meter_store *store = elem->private_data;
782 	int val;
783 
784 	val = ucontrol->value.integer.value[0];
785 
786 	/* sanity check */
787 	if (val < 0 || val >= SND_US16X08_MAX_CHANNELS)
788 		return -EINVAL;
789 
790 	store->comp_active_index = val;
791 	store->comp_index = val;
792 
793 	return 1;
794 }
795 
796 static const struct snd_kcontrol_new snd_us16x08_ch_boolean_ctl = {
797 	.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
798 	.access = SNDRV_CTL_ELEM_ACCESS_READWRITE,
799 	.count = 16,
800 	.info = snd_us16x08_switch_info,
801 	.get = snd_us16x08_channel_get,
802 	.put = snd_us16x08_channel_put,
803 	.private_value = SND_US16X08_KCSET(SND_US16X08_NO_BIAS, 1, 0, 1)
804 };
805 
806 static const struct snd_kcontrol_new snd_us16x08_ch_int_ctl = {
807 	.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
808 	.access = SNDRV_CTL_ELEM_ACCESS_READWRITE,
809 	.count = 16,
810 	.info = snd_us16x08_mix_info,
811 	.get = snd_us16x08_channel_get,
812 	.put = snd_us16x08_channel_put,
813 	.private_value = SND_US16X08_KCSET(SND_US16X08_FADER_BIAS, 1, 0, 133)
814 };
815 
816 static const struct snd_kcontrol_new snd_us16x08_pan_int_ctl = {
817 	.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
818 	.access = SNDRV_CTL_ELEM_ACCESS_READWRITE,
819 	.count = 16,
820 	.info = snd_us16x08_mix_info,
821 	.get = snd_us16x08_channel_get,
822 	.put = snd_us16x08_channel_put,
823 	.private_value = SND_US16X08_KCSET(SND_US16X08_FADER_BIAS, 1, 0, 255)
824 };
825 
826 static const struct snd_kcontrol_new snd_us16x08_master_ctl = {
827 	.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
828 	.access = SNDRV_CTL_ELEM_ACCESS_READWRITE,
829 	.count = 1,
830 	.info = snd_us16x08_master_info,
831 	.get = snd_us16x08_master_get,
832 	.put = snd_us16x08_master_put,
833 	.private_value = SND_US16X08_KCSET(SND_US16X08_FADER_BIAS, 1, 0, 133)
834 };
835 
836 static const struct snd_kcontrol_new snd_us16x08_route_ctl = {
837 	.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
838 	.access = SNDRV_CTL_ELEM_ACCESS_READWRITE,
839 	.count = 8,
840 	.info = snd_us16x08_route_info,
841 	.get = snd_us16x08_route_get,
842 	.put = snd_us16x08_route_put,
843 	.private_value = SND_US16X08_KCSET(SND_US16X08_NO_BIAS, 1, 0, 9)
844 };
845 
846 static const struct snd_kcontrol_new snd_us16x08_bus_ctl = {
847 	.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
848 	.access = SNDRV_CTL_ELEM_ACCESS_READWRITE,
849 	.count = 1,
850 	.info = snd_us16x08_switch_info,
851 	.get = snd_us16x08_bus_get,
852 	.put = snd_us16x08_bus_put,
853 	.private_value = SND_US16X08_KCSET(SND_US16X08_NO_BIAS, 1, 0, 1)
854 };
855 
856 static const struct snd_kcontrol_new snd_us16x08_compswitch_ctl = {
857 	.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
858 	.access = SNDRV_CTL_ELEM_ACCESS_READWRITE,
859 	.count = 16,
860 	.info = snd_us16x08_switch_info,
861 	.get = snd_us16x08_comp_get,
862 	.put = snd_us16x08_comp_put,
863 	.private_value = SND_US16X08_KCSET(SND_US16X08_NO_BIAS, 1, 0, 1)
864 };
865 
866 static const struct snd_kcontrol_new snd_us16x08_comp_threshold_ctl = {
867 	.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
868 	.access = SNDRV_CTL_ELEM_ACCESS_READWRITE,
869 	.count = 16,
870 	.info = snd_us16x08_mix_info,
871 	.get = snd_us16x08_comp_get,
872 	.put = snd_us16x08_comp_put,
873 	.private_value = SND_US16X08_KCSET(SND_US16X08_COMP_THRESHOLD_BIAS, 1,
874 	0, 0x20)
875 };
876 
877 static const struct snd_kcontrol_new snd_us16x08_comp_ratio_ctl = {
878 	.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
879 	.access = SNDRV_CTL_ELEM_ACCESS_READWRITE,
880 	.count = 16,
881 	.info = snd_us16x08_mix_info,
882 	.get = snd_us16x08_comp_get,
883 	.put = snd_us16x08_comp_put,
884 	.private_value = SND_US16X08_KCSET(SND_US16X08_NO_BIAS, 1, 0,
885 	sizeof(ratio_map) - 1), /*max*/
886 };
887 
888 static const struct snd_kcontrol_new snd_us16x08_comp_gain_ctl = {
889 	.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
890 	.access = SNDRV_CTL_ELEM_ACCESS_READWRITE,
891 	.count = 16,
892 	.info = snd_us16x08_mix_info,
893 	.get = snd_us16x08_comp_get,
894 	.put = snd_us16x08_comp_put,
895 	.private_value = SND_US16X08_KCSET(SND_US16X08_NO_BIAS, 1, 0, 0x14)
896 };
897 
898 static const struct snd_kcontrol_new snd_us16x08_comp_attack_ctl = {
899 	.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
900 	.access = SNDRV_CTL_ELEM_ACCESS_READWRITE,
901 	.count = 16,
902 	.info = snd_us16x08_mix_info,
903 	.get = snd_us16x08_comp_get,
904 	.put = snd_us16x08_comp_put,
905 	.private_value =
906 	SND_US16X08_KCSET(SND_US16X08_COMP_ATTACK_BIAS, 1, 0, 0xc6),
907 };
908 
909 static const struct snd_kcontrol_new snd_us16x08_comp_release_ctl = {
910 	.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
911 	.access = SNDRV_CTL_ELEM_ACCESS_READWRITE,
912 	.count = 16,
913 	.info = snd_us16x08_mix_info,
914 	.get = snd_us16x08_comp_get,
915 	.put = snd_us16x08_comp_put,
916 	.private_value =
917 	SND_US16X08_KCSET(SND_US16X08_COMP_RELEASE_BIAS, 1, 0, 0x63),
918 };
919 
920 static const struct snd_kcontrol_new snd_us16x08_eq_gain_ctl = {
921 	.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
922 	.access = SNDRV_CTL_ELEM_ACCESS_READWRITE,
923 	.count = 16,
924 	.info = snd_us16x08_mix_info,
925 	.get = snd_us16x08_eq_get,
926 	.put = snd_us16x08_eq_put,
927 	.private_value = SND_US16X08_KCSET(SND_US16X08_NO_BIAS, 1, 0, 24),
928 };
929 
930 static const struct snd_kcontrol_new snd_us16x08_eq_low_freq_ctl = {
931 	.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
932 	.access = SNDRV_CTL_ELEM_ACCESS_READWRITE,
933 	.count = 16,
934 	.info = snd_us16x08_mix_info,
935 	.get = snd_us16x08_eq_get,
936 	.put = snd_us16x08_eq_put,
937 	.private_value = SND_US16X08_KCSET(SND_US16X08_NO_BIAS, 1, 0, 0x1F),
938 };
939 
940 static const struct snd_kcontrol_new snd_us16x08_eq_mid_freq_ctl = {
941 	.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
942 	.access = SNDRV_CTL_ELEM_ACCESS_READWRITE,
943 	.count = 16,
944 	.info = snd_us16x08_mix_info,
945 	.get = snd_us16x08_eq_get,
946 	.put = snd_us16x08_eq_put,
947 	.private_value = SND_US16X08_KCSET(SND_US16X08_NO_BIAS, 1, 0, 0x3F)
948 };
949 
950 static const struct snd_kcontrol_new snd_us16x08_eq_mid_width_ctl = {
951 	.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
952 	.access = SNDRV_CTL_ELEM_ACCESS_READWRITE,
953 	.count = 16,
954 	.info = snd_us16x08_mix_info,
955 	.get = snd_us16x08_eq_get,
956 	.put = snd_us16x08_eq_put,
957 	.private_value = SND_US16X08_KCSET(SND_US16X08_NO_BIAS, 1, 0, 0x06)
958 };
959 
960 static const struct snd_kcontrol_new snd_us16x08_eq_high_freq_ctl = {
961 	.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
962 	.access = SNDRV_CTL_ELEM_ACCESS_READWRITE,
963 	.count = 16,
964 	.info = snd_us16x08_mix_info,
965 	.get = snd_us16x08_eq_get,
966 	.put = snd_us16x08_eq_put,
967 	.private_value =
968 	SND_US16X08_KCSET(SND_US16X08_EQ_HIGHFREQ_BIAS, 1, 0, 0x1F)
969 };
970 
971 static const struct snd_kcontrol_new snd_us16x08_eq_switch_ctl = {
972 	.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
973 	.access = SNDRV_CTL_ELEM_ACCESS_READWRITE,
974 	.count = 16,
975 	.info = snd_us16x08_switch_info,
976 	.get = snd_us16x08_eqswitch_get,
977 	.put = snd_us16x08_eqswitch_put,
978 	.private_value = SND_US16X08_KCSET(SND_US16X08_NO_BIAS, 1, 0, 1)
979 };
980 
981 static const struct snd_kcontrol_new snd_us16x08_meter_ctl = {
982 	.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
983 	.access = SNDRV_CTL_ELEM_ACCESS_READWRITE,
984 	.count = 1,
985 	.info = snd_us16x08_meter_info,
986 	.get = snd_us16x08_meter_get,
987 	.put = snd_us16x08_meter_put
988 };
989 
990 /* control store preparation */
991 
992 /* setup compressor store and assign default value */
993 static struct snd_us16x08_comp_store *snd_us16x08_create_comp_store(void)
994 {
995 	int i;
996 	struct snd_us16x08_comp_store *tmp;
997 
998 	tmp = kmalloc_obj(*tmp);
999 	if (!tmp)
1000 		return NULL;
1001 
1002 	for (i = 0; i < SND_US16X08_MAX_CHANNELS; i++) {
1003 		tmp->val[COMP_STORE_IDX(SND_US16X08_ID_COMP_THRESHOLD)][i]
1004 			= 0x20;
1005 		tmp->val[COMP_STORE_IDX(SND_US16X08_ID_COMP_RATIO)][i] = 0x00;
1006 		tmp->val[COMP_STORE_IDX(SND_US16X08_ID_COMP_GAIN)][i] = 0x00;
1007 		tmp->val[COMP_STORE_IDX(SND_US16X08_ID_COMP_SWITCH)][i] = 0x00;
1008 		tmp->val[COMP_STORE_IDX(SND_US16X08_ID_COMP_ATTACK)][i] = 0x00;
1009 		tmp->val[COMP_STORE_IDX(SND_US16X08_ID_COMP_RELEASE)][i] = 0x00;
1010 	}
1011 	return tmp;
1012 }
1013 
1014 /* setup EQ store and assign default values */
1015 static struct snd_us16x08_eq_store *snd_us16x08_create_eq_store(void)
1016 {
1017 	int i, b_idx;
1018 	struct snd_us16x08_eq_store *tmp;
1019 
1020 	tmp = kmalloc_obj(*tmp);
1021 	if (!tmp)
1022 		return NULL;
1023 
1024 	for (i = 0; i < SND_US16X08_MAX_CHANNELS; i++) {
1025 		for (b_idx = 0; b_idx < SND_US16X08_ID_EQ_BAND_COUNT; b_idx++) {
1026 			tmp->val[b_idx][0][i] = 0x0c;
1027 			tmp->val[b_idx][3][i] = 0x00;
1028 			switch (b_idx) {
1029 			case 0: /* EQ Low */
1030 				tmp->val[b_idx][1][i] = 0x05;
1031 				tmp->val[b_idx][2][i] = 0xff;
1032 				break;
1033 			case 1: /* EQ Mid low */
1034 				tmp->val[b_idx][1][i] = 0x0e;
1035 				tmp->val[b_idx][2][i] = 0x02;
1036 				break;
1037 			case 2: /* EQ Mid High */
1038 				tmp->val[b_idx][1][i] = 0x1b;
1039 				tmp->val[b_idx][2][i] = 0x02;
1040 				break;
1041 			case 3: /* EQ High */
1042 				tmp->val[b_idx][1][i] = 0x2f
1043 					- SND_US16X08_EQ_HIGHFREQ_BIAS;
1044 				tmp->val[b_idx][2][i] = 0xff;
1045 				break;
1046 			}
1047 		}
1048 	}
1049 	return tmp;
1050 }
1051 
1052 static struct snd_us16x08_meter_store *snd_us16x08_create_meter_store(void)
1053 {
1054 	struct snd_us16x08_meter_store *tmp;
1055 
1056 	tmp = kzalloc_obj(*tmp);
1057 	if (!tmp)
1058 		return NULL;
1059 	tmp->comp_index = 1;
1060 	tmp->comp_active_index = 0;
1061 	return tmp;
1062 }
1063 
1064 /* release elem->private_free as well; called only once for each *_store */
1065 static void elem_private_free(struct snd_kcontrol *kctl)
1066 {
1067 	struct usb_mixer_elem_info *elem = kctl->private_data;
1068 
1069 	if (elem)
1070 		kfree(elem->private_data);
1071 	kfree(elem);
1072 	kctl->private_data = NULL;
1073 }
1074 
1075 static int add_new_ctl(struct usb_mixer_interface *mixer,
1076 	const struct snd_kcontrol_new *ncontrol,
1077 	int index, int val_type, int channels,
1078 	const char *name, void *opt,
1079 	bool do_private_free,
1080 	struct usb_mixer_elem_info **elem_ret)
1081 {
1082 	struct snd_kcontrol *kctl;
1083 	struct usb_mixer_elem_info *elem;
1084 	int err;
1085 
1086 	usb_audio_dbg(mixer->chip, "us16x08 add mixer %s\n", name);
1087 
1088 	elem = kzalloc_obj(*elem);
1089 	if (!elem)
1090 		return -ENOMEM;
1091 
1092 	elem->head.mixer = mixer;
1093 	elem->head.resume = NULL;
1094 	elem->control = 0;
1095 	elem->idx_off = 0;
1096 	elem->head.id = index;
1097 	elem->val_type = val_type;
1098 	elem->channels = channels;
1099 	elem->private_data = opt;
1100 
1101 	kctl = snd_ctl_new1(ncontrol, elem);
1102 	if (!kctl) {
1103 		kfree(elem);
1104 		return -ENOMEM;
1105 	}
1106 
1107 	if (do_private_free)
1108 		kctl->private_free = elem_private_free;
1109 	else
1110 		kctl->private_free = snd_usb_mixer_elem_free;
1111 
1112 	strscpy(kctl->id.name, name, sizeof(kctl->id.name));
1113 
1114 	err = snd_usb_mixer_add_control(&elem->head, kctl);
1115 	if (err < 0)
1116 		return err;
1117 
1118 	if (elem_ret)
1119 		*elem_ret = elem;
1120 
1121 	return 0;
1122 }
1123 
1124 /* table of EQ controls */
1125 static const struct snd_us16x08_control_params eq_controls[] = {
1126 	{ /* EQ switch */
1127 		.kcontrol_new = &snd_us16x08_eq_switch_ctl,
1128 		.control_id = SND_US16X08_ID_EQENABLE,
1129 		.type = USB_MIXER_BOOLEAN,
1130 		.num_channels = 16,
1131 		.name = "EQ Switch",
1132 	},
1133 	{ /* EQ low gain */
1134 		.kcontrol_new = &snd_us16x08_eq_gain_ctl,
1135 		.control_id = SND_US16X08_ID_EQLOWLEVEL,
1136 		.type = USB_MIXER_U8,
1137 		.num_channels = 16,
1138 		.name = "EQ Low Volume",
1139 	},
1140 	{ /* EQ low freq */
1141 		.kcontrol_new = &snd_us16x08_eq_low_freq_ctl,
1142 		.control_id = SND_US16X08_ID_EQLOWFREQ,
1143 		.type = USB_MIXER_U8,
1144 		.num_channels = 16,
1145 		.name = "EQ Low Frequency",
1146 	},
1147 	{ /* EQ mid low gain */
1148 		.kcontrol_new = &snd_us16x08_eq_gain_ctl,
1149 		.control_id = SND_US16X08_ID_EQLOWMIDLEVEL,
1150 		.type = USB_MIXER_U8,
1151 		.num_channels = 16,
1152 		.name = "EQ MidLow Volume",
1153 	},
1154 	{ /* EQ mid low freq */
1155 		.kcontrol_new = &snd_us16x08_eq_mid_freq_ctl,
1156 		.control_id = SND_US16X08_ID_EQLOWMIDFREQ,
1157 		.type = USB_MIXER_U8,
1158 		.num_channels = 16,
1159 		.name = "EQ MidLow Frequency",
1160 	},
1161 	{ /* EQ mid low Q */
1162 		.kcontrol_new = &snd_us16x08_eq_mid_width_ctl,
1163 		.control_id = SND_US16X08_ID_EQLOWMIDWIDTH,
1164 		.type = USB_MIXER_U8,
1165 		.num_channels = 16,
1166 		.name = "EQ MidLow Q",
1167 	},
1168 	{ /* EQ mid high gain */
1169 		.kcontrol_new = &snd_us16x08_eq_gain_ctl,
1170 		.control_id = SND_US16X08_ID_EQHIGHMIDLEVEL,
1171 		.type = USB_MIXER_U8,
1172 		.num_channels = 16,
1173 		.name = "EQ MidHigh Volume",
1174 	},
1175 	{ /* EQ mid high freq */
1176 		.kcontrol_new = &snd_us16x08_eq_mid_freq_ctl,
1177 		.control_id = SND_US16X08_ID_EQHIGHMIDFREQ,
1178 		.type = USB_MIXER_U8,
1179 		.num_channels = 16,
1180 		.name = "EQ MidHigh Frequency",
1181 	},
1182 	{ /* EQ mid high Q */
1183 		.kcontrol_new = &snd_us16x08_eq_mid_width_ctl,
1184 		.control_id = SND_US16X08_ID_EQHIGHMIDWIDTH,
1185 		.type = USB_MIXER_U8,
1186 		.num_channels = 16,
1187 		.name = "EQ MidHigh Q",
1188 	},
1189 	{ /* EQ high gain */
1190 		.kcontrol_new = &snd_us16x08_eq_gain_ctl,
1191 		.control_id = SND_US16X08_ID_EQHIGHLEVEL,
1192 		.type = USB_MIXER_U8,
1193 		.num_channels = 16,
1194 		.name = "EQ High Volume",
1195 	},
1196 	{ /* EQ low freq */
1197 		.kcontrol_new = &snd_us16x08_eq_high_freq_ctl,
1198 		.control_id = SND_US16X08_ID_EQHIGHFREQ,
1199 		.type = USB_MIXER_U8,
1200 		.num_channels = 16,
1201 		.name = "EQ High Frequency",
1202 	},
1203 };
1204 
1205 /* table of compressor controls */
1206 static const struct snd_us16x08_control_params comp_controls[] = {
1207 	{ /* Comp enable */
1208 		.kcontrol_new = &snd_us16x08_compswitch_ctl,
1209 		.control_id = SND_US16X08_ID_COMP_SWITCH,
1210 		.type = USB_MIXER_BOOLEAN,
1211 		.num_channels = 16,
1212 		.name = "Compressor Switch",
1213 	},
1214 	{ /* Comp threshold */
1215 		.kcontrol_new = &snd_us16x08_comp_threshold_ctl,
1216 		.control_id = SND_US16X08_ID_COMP_THRESHOLD,
1217 		.type = USB_MIXER_U8,
1218 		.num_channels = 16,
1219 		.name = "Compressor Threshold Volume",
1220 	},
1221 	{ /* Comp ratio */
1222 		.kcontrol_new = &snd_us16x08_comp_ratio_ctl,
1223 		.control_id = SND_US16X08_ID_COMP_RATIO,
1224 		.type = USB_MIXER_U8,
1225 		.num_channels = 16,
1226 		.name = "Compressor Ratio",
1227 	},
1228 	{ /* Comp attack */
1229 		.kcontrol_new = &snd_us16x08_comp_attack_ctl,
1230 		.control_id = SND_US16X08_ID_COMP_ATTACK,
1231 		.type = USB_MIXER_U8,
1232 		.num_channels = 16,
1233 		.name = "Compressor Attack",
1234 	},
1235 	{ /* Comp release */
1236 		.kcontrol_new = &snd_us16x08_comp_release_ctl,
1237 		.control_id = SND_US16X08_ID_COMP_RELEASE,
1238 		.type = USB_MIXER_U8,
1239 		.num_channels = 16,
1240 		.name = "Compressor Release",
1241 	},
1242 	{ /* Comp gain */
1243 		.kcontrol_new = &snd_us16x08_comp_gain_ctl,
1244 		.control_id = SND_US16X08_ID_COMP_GAIN,
1245 		.type = USB_MIXER_U8,
1246 		.num_channels = 16,
1247 		.name = "Compressor Volume",
1248 	},
1249 };
1250 
1251 /* table of channel controls */
1252 static const struct snd_us16x08_control_params channel_controls[] = {
1253 	{ /* Phase */
1254 		.kcontrol_new = &snd_us16x08_ch_boolean_ctl,
1255 		.control_id = SND_US16X08_ID_PHASE,
1256 		.type = USB_MIXER_BOOLEAN,
1257 		.num_channels = 16,
1258 		.name = "Phase Switch",
1259 		.default_val = 0
1260 	},
1261 	{ /* Fader */
1262 		.kcontrol_new = &snd_us16x08_ch_int_ctl,
1263 		.control_id = SND_US16X08_ID_FADER,
1264 		.type = USB_MIXER_U8,
1265 		.num_channels = 16,
1266 		.name = "Line Volume",
1267 		.default_val = 127
1268 	},
1269 	{ /* Mute */
1270 		.kcontrol_new = &snd_us16x08_ch_boolean_ctl,
1271 		.control_id = SND_US16X08_ID_MUTE,
1272 		.type = USB_MIXER_BOOLEAN,
1273 		.num_channels = 16,
1274 		.name = "Mute Switch",
1275 		.default_val = 0
1276 	},
1277 	{ /* Pan */
1278 		.kcontrol_new = &snd_us16x08_pan_int_ctl,
1279 		.control_id = SND_US16X08_ID_PAN,
1280 		.type = USB_MIXER_U16,
1281 		.num_channels = 16,
1282 		.name = "Pan Left-Right Volume",
1283 		.default_val = 127
1284 	},
1285 };
1286 
1287 /* table of master controls */
1288 static const struct snd_us16x08_control_params master_controls[] = {
1289 	{ /* Master */
1290 		.kcontrol_new = &snd_us16x08_master_ctl,
1291 		.control_id = SND_US16X08_ID_FADER,
1292 		.type = USB_MIXER_U8,
1293 		.num_channels = 16,
1294 		.name = "Master Volume",
1295 		.default_val = 127
1296 	},
1297 	{ /* Bypass */
1298 		.kcontrol_new = &snd_us16x08_bus_ctl,
1299 		.control_id = SND_US16X08_ID_BYPASS,
1300 		.type = USB_MIXER_BOOLEAN,
1301 		.num_channels = 16,
1302 		.name = "DSP Bypass Switch",
1303 		.default_val = 0
1304 	},
1305 	{ /* Buss out */
1306 		.kcontrol_new = &snd_us16x08_bus_ctl,
1307 		.control_id = SND_US16X08_ID_BUSS_OUT,
1308 		.type = USB_MIXER_BOOLEAN,
1309 		.num_channels = 16,
1310 		.name = "Buss Out Switch",
1311 		.default_val = 0
1312 	},
1313 	{ /* Master mute */
1314 		.kcontrol_new = &snd_us16x08_bus_ctl,
1315 		.control_id = SND_US16X08_ID_MUTE,
1316 		.type = USB_MIXER_BOOLEAN,
1317 		.num_channels = 16,
1318 		.name = "Master Mute Switch",
1319 		.default_val = 0
1320 	},
1321 
1322 };
1323 
1324 int snd_us16x08_controls_create(struct usb_mixer_interface *mixer)
1325 {
1326 	int i, j;
1327 	int err;
1328 	struct usb_mixer_elem_info *elem;
1329 	struct snd_us16x08_comp_store *comp_store;
1330 	struct snd_us16x08_meter_store *meter_store;
1331 	struct snd_us16x08_eq_store *eq_store;
1332 
1333 	/* just check for non-MIDI interface */
1334 	if (mixer->hostif->desc.bInterfaceNumber == 3) {
1335 
1336 		/* add routing control */
1337 		err = add_new_ctl(mixer, &snd_us16x08_route_ctl,
1338 			SND_US16X08_ID_ROUTE, USB_MIXER_U8, 8, "Line Out Route",
1339 			NULL, false, &elem);
1340 		if (err < 0) {
1341 			usb_audio_dbg(mixer->chip,
1342 				"Failed to create route control, err:%d\n",
1343 				err);
1344 			return err;
1345 		}
1346 		for (i = 0; i < 8; i++)
1347 			elem->cache_val[i] = i < 2 ? i : i + 2;
1348 		elem->cached = 0xff;
1349 
1350 		/* create compressor mixer elements */
1351 		comp_store = snd_us16x08_create_comp_store();
1352 		if (!comp_store)
1353 			return -ENOMEM;
1354 
1355 		/* add master controls */
1356 		for (i = 0; i < ARRAY_SIZE(master_controls); i++) {
1357 
1358 			err = add_new_ctl(mixer,
1359 				master_controls[i].kcontrol_new,
1360 				master_controls[i].control_id,
1361 				master_controls[i].type,
1362 				master_controls[i].num_channels,
1363 				master_controls[i].name,
1364 				comp_store,
1365 				i == 0, /* release comp_store only once */
1366 				&elem);
1367 			if (err < 0)
1368 				return err;
1369 			elem->cache_val[0] = master_controls[i].default_val;
1370 			elem->cached = 1;
1371 		}
1372 
1373 		/* add channel controls */
1374 		for (i = 0; i < ARRAY_SIZE(channel_controls); i++) {
1375 
1376 			err = add_new_ctl(mixer,
1377 				channel_controls[i].kcontrol_new,
1378 				channel_controls[i].control_id,
1379 				channel_controls[i].type,
1380 				channel_controls[i].num_channels,
1381 				channel_controls[i].name,
1382 				comp_store,
1383 				false, &elem);
1384 			if (err < 0)
1385 				return err;
1386 			for (j = 0; j < SND_US16X08_MAX_CHANNELS; j++) {
1387 				elem->cache_val[j] =
1388 					channel_controls[i].default_val;
1389 			}
1390 			elem->cached = 0xffff;
1391 		}
1392 
1393 		/* create eq store */
1394 		eq_store = snd_us16x08_create_eq_store();
1395 		if (!eq_store)
1396 			return -ENOMEM;
1397 
1398 		/* add EQ controls */
1399 		for (i = 0; i < ARRAY_SIZE(eq_controls); i++) {
1400 
1401 			err = add_new_ctl(mixer,
1402 				eq_controls[i].kcontrol_new,
1403 				eq_controls[i].control_id,
1404 				eq_controls[i].type,
1405 				eq_controls[i].num_channels,
1406 				eq_controls[i].name,
1407 				eq_store,
1408 				i == 0, /* release eq_store only once */
1409 				NULL);
1410 			if (err < 0)
1411 				return err;
1412 		}
1413 
1414 		/* add compressor controls */
1415 		for (i = 0; i < ARRAY_SIZE(comp_controls); i++) {
1416 
1417 			err = add_new_ctl(mixer,
1418 				comp_controls[i].kcontrol_new,
1419 				comp_controls[i].control_id,
1420 				comp_controls[i].type,
1421 				comp_controls[i].num_channels,
1422 				comp_controls[i].name,
1423 				comp_store,
1424 				false, NULL);
1425 			if (err < 0)
1426 				return err;
1427 		}
1428 
1429 		/* create meters store */
1430 		meter_store = snd_us16x08_create_meter_store();
1431 		if (!meter_store)
1432 			return -ENOMEM;
1433 
1434 		/* meter function 'get' must access to compressor store
1435 		 * so place a reference here
1436 		 */
1437 		meter_store->comp_store = comp_store;
1438 		err = add_new_ctl(mixer, &snd_us16x08_meter_ctl,
1439 			SND_US16X08_ID_METER, USB_MIXER_U16, 0, "Level Meter",
1440 			meter_store, true, NULL);
1441 		if (err < 0)
1442 			return err;
1443 	}
1444 
1445 	return 0;
1446 }
1447