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