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