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