1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130#include <linux/slab.h>
131#include <linux/usb.h>
132#include <linux/usb/audio-v2.h>
133
134#include <sound/core.h>
135#include <sound/control.h>
136#include <sound/tlv.h>
137
138#include "usbaudio.h"
139#include "mixer.h"
140#include "helper.h"
141#include "power.h"
142
143#include "mixer_scarlett.h"
144
145
146#define SND_SCARLETT_LEVEL_BIAS 128
147#define SND_SCARLETT_MATRIX_IN_MAX 18
148#define SND_SCARLETT_CONTROLS_MAX 10
149#define SND_SCARLETT_OFFSETS_MAX 5
150
151enum {
152 SCARLETT_OUTPUTS,
153 SCARLETT_SWITCH_IMPEDANCE,
154 SCARLETT_SWITCH_PAD,
155};
156
157enum {
158 SCARLETT_OFFSET_PCM = 0,
159 SCARLETT_OFFSET_ANALOG = 1,
160 SCARLETT_OFFSET_SPDIF = 2,
161 SCARLETT_OFFSET_ADAT = 3,
162 SCARLETT_OFFSET_MIX = 4,
163};
164
165struct scarlett_mixer_elem_enum_info {
166 int start;
167 int len;
168 int offsets[SND_SCARLETT_OFFSETS_MAX];
169 char const * const *names;
170};
171
172struct scarlett_mixer_control {
173 unsigned char num;
174 unsigned char type;
175 const char *name;
176};
177
178struct scarlett_device_info {
179 int matrix_in;
180 int matrix_out;
181 int input_len;
182 int output_len;
183
184 struct scarlett_mixer_elem_enum_info opt_master;
185 struct scarlett_mixer_elem_enum_info opt_matrix;
186
187
188 int matrix_mux_init[SND_SCARLETT_MATRIX_IN_MAX];
189
190 int num_controls;
191 const struct scarlett_mixer_control controls[SND_SCARLETT_CONTROLS_MAX];
192};
193
194
195
196static const struct scarlett_mixer_elem_enum_info opt_pad = {
197 .start = 0,
198 .len = 2,
199 .offsets = {},
200 .names = (char const * const []){
201 "0dB", "-10dB"
202 }
203};
204
205static const struct scarlett_mixer_elem_enum_info opt_impedance = {
206 .start = 0,
207 .len = 2,
208 .offsets = {},
209 .names = (char const * const []){
210 "Line", "Hi-Z"
211 }
212};
213
214static const struct scarlett_mixer_elem_enum_info opt_clock = {
215 .start = 1,
216 .len = 3,
217 .offsets = {},
218 .names = (char const * const []){
219 "Internal", "SPDIF", "ADAT"
220 }
221};
222
223static const struct scarlett_mixer_elem_enum_info opt_sync = {
224 .start = 0,
225 .len = 2,
226 .offsets = {},
227 .names = (char const * const []){
228 "No Lock", "Locked"
229 }
230};
231
232static int scarlett_ctl_switch_info(struct snd_kcontrol *kctl,
233 struct snd_ctl_elem_info *uinfo)
234{
235 struct usb_mixer_elem_info *elem = kctl->private_data;
236
237 uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN;
238 uinfo->count = elem->channels;
239 uinfo->value.integer.min = 0;
240 uinfo->value.integer.max = 1;
241 return 0;
242}
243
244static int scarlett_ctl_switch_get(struct snd_kcontrol *kctl,
245 struct snd_ctl_elem_value *ucontrol)
246{
247 struct usb_mixer_elem_info *elem = kctl->private_data;
248 int i, err, val;
249
250 for (i = 0; i < elem->channels; i++) {
251 err = snd_usb_get_cur_mix_value(elem, i, i, &val);
252 if (err < 0)
253 return err;
254
255 val = !val;
256 ucontrol->value.integer.value[i] = val;
257 }
258
259 return 0;
260}
261
262static int scarlett_ctl_switch_put(struct snd_kcontrol *kctl,
263 struct snd_ctl_elem_value *ucontrol)
264{
265 struct usb_mixer_elem_info *elem = kctl->private_data;
266 int i, changed = 0;
267 int err, oval, val;
268
269 for (i = 0; i < elem->channels; i++) {
270 err = snd_usb_get_cur_mix_value(elem, i, i, &oval);
271 if (err < 0)
272 return err;
273
274 val = ucontrol->value.integer.value[i];
275 val = !val;
276 if (oval != val) {
277 err = snd_usb_set_cur_mix_value(elem, i, i, val);
278 if (err < 0)
279 return err;
280
281 changed = 1;
282 }
283 }
284
285 return changed;
286}
287
288static int scarlett_ctl_resume(struct usb_mixer_elem_list *list)
289{
290 struct usb_mixer_elem_info *elem =
291 container_of(list, struct usb_mixer_elem_info, head);
292 int i;
293
294 for (i = 0; i < elem->channels; i++)
295 if (elem->cached & (1 << i))
296 snd_usb_set_cur_mix_value(elem, i, i,
297 elem->cache_val[i]);
298 return 0;
299}
300
301static int scarlett_ctl_info(struct snd_kcontrol *kctl,
302 struct snd_ctl_elem_info *uinfo)
303{
304 struct usb_mixer_elem_info *elem = kctl->private_data;
305
306 uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
307 uinfo->count = elem->channels;
308 uinfo->value.integer.min = 0;
309 uinfo->value.integer.max = (int)kctl->private_value +
310 SND_SCARLETT_LEVEL_BIAS;
311 uinfo->value.integer.step = 1;
312 return 0;
313}
314
315static int scarlett_ctl_get(struct snd_kcontrol *kctl,
316 struct snd_ctl_elem_value *ucontrol)
317{
318 struct usb_mixer_elem_info *elem = kctl->private_data;
319 int i, err, val;
320
321 for (i = 0; i < elem->channels; i++) {
322 err = snd_usb_get_cur_mix_value(elem, i, i, &val);
323 if (err < 0)
324 return err;
325
326 val = clamp(val / 256, -128, (int)kctl->private_value) +
327 SND_SCARLETT_LEVEL_BIAS;
328 ucontrol->value.integer.value[i] = val;
329 }
330
331 return 0;
332}
333
334static int scarlett_ctl_put(struct snd_kcontrol *kctl,
335 struct snd_ctl_elem_value *ucontrol)
336{
337 struct usb_mixer_elem_info *elem = kctl->private_data;
338 int i, changed = 0;
339 int err, oval, val;
340
341 for (i = 0; i < elem->channels; i++) {
342 err = snd_usb_get_cur_mix_value(elem, i, i, &oval);
343 if (err < 0)
344 return err;
345
346 val = ucontrol->value.integer.value[i] -
347 SND_SCARLETT_LEVEL_BIAS;
348 val = val * 256;
349 if (oval != val) {
350 err = snd_usb_set_cur_mix_value(elem, i, i, val);
351 if (err < 0)
352 return err;
353
354 changed = 1;
355 }
356 }
357
358 return changed;
359}
360
361static void scarlett_generate_name(int i, char *dst, int offsets[])
362{
363 if (i > offsets[SCARLETT_OFFSET_MIX])
364 sprintf(dst, "Mix %c",
365 'A'+(i - offsets[SCARLETT_OFFSET_MIX] - 1));
366 else if (i > offsets[SCARLETT_OFFSET_ADAT])
367 sprintf(dst, "ADAT %d", i - offsets[SCARLETT_OFFSET_ADAT]);
368 else if (i > offsets[SCARLETT_OFFSET_SPDIF])
369 sprintf(dst, "SPDIF %d", i - offsets[SCARLETT_OFFSET_SPDIF]);
370 else if (i > offsets[SCARLETT_OFFSET_ANALOG])
371 sprintf(dst, "Analog %d", i - offsets[SCARLETT_OFFSET_ANALOG]);
372 else if (i > offsets[SCARLETT_OFFSET_PCM])
373 sprintf(dst, "PCM %d", i - offsets[SCARLETT_OFFSET_PCM]);
374 else
375 sprintf(dst, "Off");
376}
377
378static int scarlett_ctl_enum_dynamic_info(struct snd_kcontrol *kctl,
379 struct snd_ctl_elem_info *uinfo)
380{
381 struct usb_mixer_elem_info *elem = kctl->private_data;
382 struct scarlett_mixer_elem_enum_info *opt = elem->private_data;
383 unsigned int items = opt->len;
384
385 uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
386 uinfo->count = elem->channels;
387 uinfo->value.enumerated.items = items;
388
389 if (uinfo->value.enumerated.item >= items)
390 uinfo->value.enumerated.item = items - 1;
391
392
393 scarlett_generate_name(uinfo->value.enumerated.item,
394 uinfo->value.enumerated.name,
395 opt->offsets);
396
397 return 0;
398}
399
400static int scarlett_ctl_enum_info(struct snd_kcontrol *kctl,
401 struct snd_ctl_elem_info *uinfo)
402{
403 struct usb_mixer_elem_info *elem = kctl->private_data;
404 struct scarlett_mixer_elem_enum_info *opt = elem->private_data;
405
406 return snd_ctl_enum_info(uinfo, elem->channels, opt->len,
407 (const char * const *)opt->names);
408}
409
410static int scarlett_ctl_enum_get(struct snd_kcontrol *kctl,
411 struct snd_ctl_elem_value *ucontrol)
412{
413 struct usb_mixer_elem_info *elem = kctl->private_data;
414 struct scarlett_mixer_elem_enum_info *opt = elem->private_data;
415 int err, val;
416
417 err = snd_usb_get_cur_mix_value(elem, 0, 0, &val);
418 if (err < 0)
419 return err;
420
421 val = clamp(val - opt->start, 0, opt->len-1);
422
423 ucontrol->value.enumerated.item[0] = val;
424
425 return 0;
426}
427
428static int scarlett_ctl_enum_put(struct snd_kcontrol *kctl,
429 struct snd_ctl_elem_value *ucontrol)
430{
431 struct usb_mixer_elem_info *elem = kctl->private_data;
432 struct scarlett_mixer_elem_enum_info *opt = elem->private_data;
433 int err, oval, val;
434
435 err = snd_usb_get_cur_mix_value(elem, 0, 0, &oval);
436 if (err < 0)
437 return err;
438
439 val = ucontrol->value.integer.value[0];
440 val = val + opt->start;
441 if (val != oval) {
442 snd_usb_set_cur_mix_value(elem, 0, 0, val);
443 return 1;
444 }
445 return 0;
446}
447
448static int scarlett_ctl_enum_resume(struct usb_mixer_elem_list *list)
449{
450 struct usb_mixer_elem_info *elem =
451 container_of(list, struct usb_mixer_elem_info, head);
452
453 if (elem->cached)
454 snd_usb_set_cur_mix_value(elem, 0, 0, *elem->cache_val);
455 return 0;
456}
457
458static int scarlett_ctl_meter_get(struct snd_kcontrol *kctl,
459 struct snd_ctl_elem_value *ucontrol)
460{
461 struct usb_mixer_elem_info *elem = kctl->private_data;
462 struct snd_usb_audio *chip = elem->head.mixer->chip;
463 unsigned char buf[2 * MAX_CHANNELS] = {0, };
464 int wValue = (elem->control << 8) | elem->idx_off;
465 int idx = snd_usb_ctrl_intf(chip) | (elem->head.id << 8);
466 int err;
467
468 err = snd_usb_ctl_msg(chip->dev,
469 usb_rcvctrlpipe(chip->dev, 0),
470 UAC2_CS_MEM,
471 USB_RECIP_INTERFACE | USB_TYPE_CLASS |
472 USB_DIR_IN, wValue, idx, buf, elem->channels);
473 if (err < 0)
474 return err;
475
476 ucontrol->value.enumerated.item[0] = clamp((int)buf[0], 0, 1);
477 return 0;
478}
479
480static const struct snd_kcontrol_new usb_scarlett_ctl_switch = {
481 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
482 .name = "",
483 .info = scarlett_ctl_switch_info,
484 .get = scarlett_ctl_switch_get,
485 .put = scarlett_ctl_switch_put,
486};
487
488static const DECLARE_TLV_DB_SCALE(db_scale_scarlett_gain, -12800, 100, 0);
489
490static const struct snd_kcontrol_new usb_scarlett_ctl = {
491 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
492 .access = SNDRV_CTL_ELEM_ACCESS_READWRITE |
493 SNDRV_CTL_ELEM_ACCESS_TLV_READ,
494 .name = "",
495 .info = scarlett_ctl_info,
496 .get = scarlett_ctl_get,
497 .put = scarlett_ctl_put,
498 .private_value = 6,
499 .tlv = { .p = db_scale_scarlett_gain }
500};
501
502static const struct snd_kcontrol_new usb_scarlett_ctl_master = {
503 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
504 .access = SNDRV_CTL_ELEM_ACCESS_READWRITE |
505 SNDRV_CTL_ELEM_ACCESS_TLV_READ,
506 .name = "",
507 .info = scarlett_ctl_info,
508 .get = scarlett_ctl_get,
509 .put = scarlett_ctl_put,
510 .private_value = 6,
511 .tlv = { .p = db_scale_scarlett_gain }
512};
513
514static const struct snd_kcontrol_new usb_scarlett_ctl_enum = {
515 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
516 .name = "",
517 .info = scarlett_ctl_enum_info,
518 .get = scarlett_ctl_enum_get,
519 .put = scarlett_ctl_enum_put,
520};
521
522static const struct snd_kcontrol_new usb_scarlett_ctl_dynamic_enum = {
523 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
524 .name = "",
525 .info = scarlett_ctl_enum_dynamic_info,
526 .get = scarlett_ctl_enum_get,
527 .put = scarlett_ctl_enum_put,
528};
529
530static const struct snd_kcontrol_new usb_scarlett_ctl_sync = {
531 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
532 .access = SNDRV_CTL_ELEM_ACCESS_READ | SNDRV_CTL_ELEM_ACCESS_VOLATILE,
533 .name = "",
534 .info = scarlett_ctl_enum_info,
535 .get = scarlett_ctl_meter_get,
536};
537
538static int add_new_ctl(struct usb_mixer_interface *mixer,
539 const struct snd_kcontrol_new *ncontrol,
540 usb_mixer_elem_resume_func_t resume,
541 int index, int offset, int num,
542 int val_type, int channels, const char *name,
543 const struct scarlett_mixer_elem_enum_info *opt,
544 struct usb_mixer_elem_info **elem_ret
545)
546{
547 struct snd_kcontrol *kctl;
548 struct usb_mixer_elem_info *elem;
549 int err;
550
551 elem = kzalloc(sizeof(*elem), GFP_KERNEL);
552 if (!elem)
553 return -ENOMEM;
554
555 elem->head.mixer = mixer;
556 elem->head.resume = resume;
557 elem->control = offset;
558 elem->idx_off = num;
559 elem->head.id = index;
560 elem->val_type = val_type;
561
562 elem->channels = channels;
563
564
565 elem->private_data = (void *)opt;
566
567 kctl = snd_ctl_new1(ncontrol, elem);
568 if (!kctl) {
569 kfree(elem);
570 return -ENOMEM;
571 }
572 kctl->private_free = snd_usb_mixer_elem_free;
573
574 strlcpy(kctl->id.name, name, sizeof(kctl->id.name));
575
576 err = snd_usb_mixer_add_control(&elem->head, kctl);
577 if (err < 0)
578 return err;
579
580 if (elem_ret)
581 *elem_ret = elem;
582
583 return 0;
584}
585
586static int add_output_ctls(struct usb_mixer_interface *mixer,
587 int index, const char *name,
588 const struct scarlett_device_info *info)
589{
590 int err;
591 char mx[SNDRV_CTL_ELEM_ID_NAME_MAXLEN];
592 struct usb_mixer_elem_info *elem;
593
594
595 snprintf(mx, sizeof(mx), "Master %d (%s) Playback Switch",
596 index + 1, name);
597 err = add_new_ctl(mixer, &usb_scarlett_ctl_switch,
598 scarlett_ctl_resume, 0x0a, 0x01,
599 2*index+1, USB_MIXER_S16, 2, mx, NULL, &elem);
600 if (err < 0)
601 return err;
602
603
604 snprintf(mx, sizeof(mx), "Master %d (%s) Playback Volume",
605 index + 1, name);
606 err = add_new_ctl(mixer, &usb_scarlett_ctl_master,
607 scarlett_ctl_resume, 0x0a, 0x02,
608 2*index+1, USB_MIXER_S16, 2, mx, NULL, &elem);
609 if (err < 0)
610 return err;
611
612
613 snprintf(mx, sizeof(mx), "Master %dL (%s) Source Playback Enum",
614 index + 1, name);
615 err = add_new_ctl(mixer, &usb_scarlett_ctl_dynamic_enum,
616 scarlett_ctl_enum_resume, 0x33, 0x00,
617 2*index, USB_MIXER_S16, 1, mx, &info->opt_master,
618 &elem);
619 if (err < 0)
620 return err;
621
622
623 snprintf(mx, sizeof(mx), "Master %dR (%s) Source Playback Enum",
624 index + 1, name);
625 err = add_new_ctl(mixer, &usb_scarlett_ctl_dynamic_enum,
626 scarlett_ctl_enum_resume, 0x33, 0x00,
627 2*index+1, USB_MIXER_S16, 1, mx, &info->opt_master,
628 &elem);
629 if (err < 0)
630 return err;
631
632 return 0;
633}
634
635
636
637
638static struct scarlett_device_info s6i6_info = {
639 .matrix_in = 18,
640 .matrix_out = 8,
641 .input_len = 6,
642 .output_len = 6,
643
644 .opt_master = {
645 .start = -1,
646 .len = 27,
647 .offsets = {0, 12, 16, 18, 18},
648 .names = NULL
649 },
650
651 .opt_matrix = {
652 .start = -1,
653 .len = 19,
654 .offsets = {0, 12, 16, 18, 18},
655 .names = NULL
656 },
657
658 .num_controls = 9,
659 .controls = {
660 { .num = 0, .type = SCARLETT_OUTPUTS, .name = "Monitor" },
661 { .num = 1, .type = SCARLETT_OUTPUTS, .name = "Headphone" },
662 { .num = 2, .type = SCARLETT_OUTPUTS, .name = "SPDIF" },
663 { .num = 1, .type = SCARLETT_SWITCH_IMPEDANCE, .name = NULL},
664 { .num = 1, .type = SCARLETT_SWITCH_PAD, .name = NULL},
665 { .num = 2, .type = SCARLETT_SWITCH_IMPEDANCE, .name = NULL},
666 { .num = 2, .type = SCARLETT_SWITCH_PAD, .name = NULL},
667 { .num = 3, .type = SCARLETT_SWITCH_PAD, .name = NULL},
668 { .num = 4, .type = SCARLETT_SWITCH_PAD, .name = NULL},
669 },
670
671 .matrix_mux_init = {
672 12, 13, 14, 15,
673 16, 17,
674 0, 1, 2, 3, 4, 5, 6, 7,
675 8, 9, 10, 11
676 }
677};
678
679
680static struct scarlett_device_info s8i6_info = {
681 .matrix_in = 18,
682 .matrix_out = 6,
683 .input_len = 8,
684 .output_len = 6,
685
686 .opt_master = {
687 .start = -1,
688 .len = 25,
689 .offsets = {0, 12, 16, 18, 18},
690 .names = NULL
691 },
692
693 .opt_matrix = {
694 .start = -1,
695 .len = 19,
696 .offsets = {0, 12, 16, 18, 18},
697 .names = NULL
698 },
699
700 .num_controls = 7,
701 .controls = {
702 { .num = 0, .type = SCARLETT_OUTPUTS, .name = "Monitor" },
703 { .num = 1, .type = SCARLETT_OUTPUTS, .name = "Headphone" },
704 { .num = 2, .type = SCARLETT_OUTPUTS, .name = "SPDIF" },
705 { .num = 1, .type = SCARLETT_SWITCH_IMPEDANCE, .name = NULL},
706 { .num = 2, .type = SCARLETT_SWITCH_IMPEDANCE, .name = NULL},
707 { .num = 3, .type = SCARLETT_SWITCH_PAD, .name = NULL},
708 { .num = 4, .type = SCARLETT_SWITCH_PAD, .name = NULL},
709 },
710
711 .matrix_mux_init = {
712 12, 13, 14, 15,
713 16, 17,
714 0, 1, 2, 3, 4, 5, 6, 7,
715 8, 9, 10, 11
716 }
717};
718
719static struct scarlett_device_info s18i6_info = {
720 .matrix_in = 18,
721 .matrix_out = 6,
722 .input_len = 18,
723 .output_len = 6,
724
725 .opt_master = {
726 .start = -1,
727 .len = 31,
728 .offsets = {0, 6, 14, 16, 24},
729 .names = NULL,
730 },
731
732 .opt_matrix = {
733 .start = -1,
734 .len = 25,
735 .offsets = {0, 6, 14, 16, 24},
736 .names = NULL,
737 },
738
739 .num_controls = 5,
740 .controls = {
741 { .num = 0, .type = SCARLETT_OUTPUTS, .name = "Monitor" },
742 { .num = 1, .type = SCARLETT_OUTPUTS, .name = "Headphone" },
743 { .num = 2, .type = SCARLETT_OUTPUTS, .name = "SPDIF" },
744 { .num = 1, .type = SCARLETT_SWITCH_IMPEDANCE, .name = NULL},
745 { .num = 2, .type = SCARLETT_SWITCH_IMPEDANCE, .name = NULL},
746 },
747
748 .matrix_mux_init = {
749 6, 7, 8, 9, 10, 11, 12, 13,
750 16, 17, 18, 19, 20, 21,
751 14, 15,
752 0, 1
753 }
754};
755
756static struct scarlett_device_info s18i8_info = {
757 .matrix_in = 18,
758 .matrix_out = 8,
759 .input_len = 18,
760 .output_len = 8,
761
762 .opt_master = {
763 .start = -1,
764 .len = 35,
765 .offsets = {0, 8, 16, 18, 26},
766 .names = NULL
767 },
768
769 .opt_matrix = {
770 .start = -1,
771 .len = 27,
772 .offsets = {0, 8, 16, 18, 26},
773 .names = NULL
774 },
775
776 .num_controls = 10,
777 .controls = {
778 { .num = 0, .type = SCARLETT_OUTPUTS, .name = "Monitor" },
779 { .num = 1, .type = SCARLETT_OUTPUTS, .name = "Headphone 1" },
780 { .num = 2, .type = SCARLETT_OUTPUTS, .name = "Headphone 2" },
781 { .num = 3, .type = SCARLETT_OUTPUTS, .name = "SPDIF" },
782 { .num = 1, .type = SCARLETT_SWITCH_IMPEDANCE, .name = NULL},
783 { .num = 1, .type = SCARLETT_SWITCH_PAD, .name = NULL},
784 { .num = 2, .type = SCARLETT_SWITCH_IMPEDANCE, .name = NULL},
785 { .num = 2, .type = SCARLETT_SWITCH_PAD, .name = NULL},
786 { .num = 3, .type = SCARLETT_SWITCH_PAD, .name = NULL},
787 { .num = 4, .type = SCARLETT_SWITCH_PAD, .name = NULL},
788 },
789
790 .matrix_mux_init = {
791 8, 9, 10, 11, 12, 13, 14, 15,
792 18, 19, 20, 21, 22, 23,
793 16, 17,
794 0, 1
795 }
796};
797
798static struct scarlett_device_info s18i20_info = {
799 .matrix_in = 18,
800 .matrix_out = 8,
801 .input_len = 18,
802 .output_len = 20,
803
804 .opt_master = {
805 .start = -1,
806 .len = 47,
807 .offsets = {0, 20, 28, 30, 38},
808 .names = NULL
809 },
810
811 .opt_matrix = {
812 .start = -1,
813 .len = 39,
814 .offsets = {0, 20, 28, 30, 38},
815 .names = NULL
816 },
817
818 .num_controls = 10,
819 .controls = {
820 { .num = 0, .type = SCARLETT_OUTPUTS, .name = "Monitor" },
821 { .num = 1, .type = SCARLETT_OUTPUTS, .name = "Line 3/4" },
822 { .num = 2, .type = SCARLETT_OUTPUTS, .name = "Line 5/6" },
823 { .num = 3, .type = SCARLETT_OUTPUTS, .name = "Line 7/8" },
824 { .num = 4, .type = SCARLETT_OUTPUTS, .name = "Line 9/10" },
825 { .num = 5, .type = SCARLETT_OUTPUTS, .name = "SPDIF" },
826 { .num = 6, .type = SCARLETT_OUTPUTS, .name = "ADAT 1/2" },
827 { .num = 7, .type = SCARLETT_OUTPUTS, .name = "ADAT 3/4" },
828 { .num = 8, .type = SCARLETT_OUTPUTS, .name = "ADAT 5/6" },
829 { .num = 9, .type = SCARLETT_OUTPUTS, .name = "ADAT 7/8" },
830
831
832
833
834
835
836 },
837
838 .matrix_mux_init = {
839 20, 21, 22, 23, 24, 25, 26, 27,
840 30, 31, 32, 33, 34, 35,
841 28, 29,
842 0, 1
843 }
844};
845
846
847static int scarlett_controls_create_generic(struct usb_mixer_interface *mixer,
848 struct scarlett_device_info *info)
849{
850 int i, err;
851 char mx[SNDRV_CTL_ELEM_ID_NAME_MAXLEN];
852 const struct scarlett_mixer_control *ctl;
853 struct usb_mixer_elem_info *elem;
854
855
856 err = add_new_ctl(mixer, &usb_scarlett_ctl_switch,
857 scarlett_ctl_resume, 0x0a, 0x01, 0,
858 USB_MIXER_S16, 1, "Master Playback Switch", NULL,
859 &elem);
860 if (err < 0)
861 return err;
862
863 err = add_new_ctl(mixer, &usb_scarlett_ctl_master,
864 scarlett_ctl_resume, 0x0a, 0x02, 0,
865 USB_MIXER_S16, 1, "Master Playback Volume", NULL,
866 &elem);
867 if (err < 0)
868 return err;
869
870
871 for (i = 0; i < info->num_controls; i++) {
872 ctl = &info->controls[i];
873
874 switch (ctl->type) {
875 case SCARLETT_OUTPUTS:
876 err = add_output_ctls(mixer, ctl->num, ctl->name, info);
877 if (err < 0)
878 return err;
879 break;
880 case SCARLETT_SWITCH_IMPEDANCE:
881 sprintf(mx, "Input %d Impedance Switch", ctl->num);
882 err = add_new_ctl(mixer, &usb_scarlett_ctl_enum,
883 scarlett_ctl_enum_resume, 0x01,
884 0x09, ctl->num, USB_MIXER_S16, 1, mx,
885 &opt_impedance, &elem);
886 if (err < 0)
887 return err;
888 break;
889 case SCARLETT_SWITCH_PAD:
890 sprintf(mx, "Input %d Pad Switch", ctl->num);
891 err = add_new_ctl(mixer, &usb_scarlett_ctl_enum,
892 scarlett_ctl_enum_resume, 0x01,
893 0x0b, ctl->num, USB_MIXER_S16, 1, mx,
894 &opt_pad, &elem);
895 if (err < 0)
896 return err;
897 break;
898 }
899 }
900
901 return 0;
902}
903
904
905
906
907int snd_scarlett_controls_create(struct usb_mixer_interface *mixer)
908{
909 int err, i, o;
910 char mx[SNDRV_CTL_ELEM_ID_NAME_MAXLEN];
911 struct scarlett_device_info *info;
912 struct usb_mixer_elem_info *elem;
913 static char sample_rate_buffer[4] = { '\x80', '\xbb', '\x00', '\x00' };
914
915
916 if (!mixer->protocol)
917 return 0;
918
919 switch (mixer->chip->usb_id) {
920 case USB_ID(0x1235, 0x8012):
921 info = &s6i6_info;
922 break;
923 case USB_ID(0x1235, 0x8002):
924 info = &s8i6_info;
925 break;
926 case USB_ID(0x1235, 0x8004):
927 info = &s18i6_info;
928 break;
929 case USB_ID(0x1235, 0x8014):
930 info = &s18i8_info;
931 break;
932 case USB_ID(0x1235, 0x800c):
933 info = &s18i20_info;
934 break;
935 default:
936 return -EINVAL;
937 }
938
939
940 err = scarlett_controls_create_generic(mixer, info);
941 if (err < 0)
942 return err;
943
944
945 for (i = 0; i < info->matrix_in; i++) {
946 snprintf(mx, sizeof(mx), "Matrix %02d Input Playback Route",
947 i+1);
948 err = add_new_ctl(mixer, &usb_scarlett_ctl_dynamic_enum,
949 scarlett_ctl_enum_resume, 0x32,
950 0x06, i, USB_MIXER_S16, 1, mx,
951 &info->opt_matrix, &elem);
952 if (err < 0)
953 return err;
954
955 for (o = 0; o < info->matrix_out; o++) {
956 sprintf(mx, "Matrix %02d Mix %c Playback Volume", i+1,
957 o+'A');
958 err = add_new_ctl(mixer, &usb_scarlett_ctl,
959 scarlett_ctl_resume, 0x3c, 0x00,
960 (i << 3) + (o & 0x07), USB_MIXER_S16,
961 1, mx, NULL, &elem);
962 if (err < 0)
963 return err;
964
965 }
966 }
967
968 for (i = 0; i < info->input_len; i++) {
969 snprintf(mx, sizeof(mx), "Input Source %02d Capture Route",
970 i+1);
971 err = add_new_ctl(mixer, &usb_scarlett_ctl_dynamic_enum,
972 scarlett_ctl_enum_resume, 0x34,
973 0x00, i, USB_MIXER_S16, 1, mx,
974 &info->opt_master, &elem);
975 if (err < 0)
976 return err;
977 }
978
979
980 err = add_new_ctl(mixer, &usb_scarlett_ctl_enum,
981 scarlett_ctl_enum_resume, 0x28, 0x01, 0,
982 USB_MIXER_U8, 1, "Sample Clock Source",
983 &opt_clock, &elem);
984 if (err < 0)
985 return err;
986
987
988 err = add_new_ctl(mixer, &usb_scarlett_ctl_sync, NULL, 0x3c, 0x00, 2,
989 USB_MIXER_U8, 1, "Sample Clock Sync Status",
990 &opt_sync, &elem);
991 if (err < 0)
992 return err;
993
994
995 err = snd_usb_ctl_msg(mixer->chip->dev,
996 usb_sndctrlpipe(mixer->chip->dev, 0), UAC2_CS_CUR,
997 USB_RECIP_INTERFACE | USB_TYPE_CLASS |
998 USB_DIR_OUT, 0x0100, snd_usb_ctrl_intf(mixer->chip) |
999 (0x29 << 8), sample_rate_buffer, 4);
1000 if (err < 0)
1001 return err;
1002
1003 return err;
1004}
1005