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 = mixer_elem_list_to_info(list);
291 int i;
292
293 for (i = 0; i < elem->channels; i++)
294 if (elem->cached & (1 << i))
295 snd_usb_set_cur_mix_value(elem, i, i,
296 elem->cache_val[i]);
297 return 0;
298}
299
300static int scarlett_ctl_info(struct snd_kcontrol *kctl,
301 struct snd_ctl_elem_info *uinfo)
302{
303 struct usb_mixer_elem_info *elem = kctl->private_data;
304
305 uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
306 uinfo->count = elem->channels;
307 uinfo->value.integer.min = 0;
308 uinfo->value.integer.max = (int)kctl->private_value +
309 SND_SCARLETT_LEVEL_BIAS;
310 uinfo->value.integer.step = 1;
311 return 0;
312}
313
314static int scarlett_ctl_get(struct snd_kcontrol *kctl,
315 struct snd_ctl_elem_value *ucontrol)
316{
317 struct usb_mixer_elem_info *elem = kctl->private_data;
318 int i, err, val;
319
320 for (i = 0; i < elem->channels; i++) {
321 err = snd_usb_get_cur_mix_value(elem, i, i, &val);
322 if (err < 0)
323 return err;
324
325 val = clamp(val / 256, -128, (int)kctl->private_value) +
326 SND_SCARLETT_LEVEL_BIAS;
327 ucontrol->value.integer.value[i] = val;
328 }
329
330 return 0;
331}
332
333static int scarlett_ctl_put(struct snd_kcontrol *kctl,
334 struct snd_ctl_elem_value *ucontrol)
335{
336 struct usb_mixer_elem_info *elem = kctl->private_data;
337 int i, changed = 0;
338 int err, oval, val;
339
340 for (i = 0; i < elem->channels; i++) {
341 err = snd_usb_get_cur_mix_value(elem, i, i, &oval);
342 if (err < 0)
343 return err;
344
345 val = ucontrol->value.integer.value[i] -
346 SND_SCARLETT_LEVEL_BIAS;
347 val = val * 256;
348 if (oval != val) {
349 err = snd_usb_set_cur_mix_value(elem, i, i, val);
350 if (err < 0)
351 return err;
352
353 changed = 1;
354 }
355 }
356
357 return changed;
358}
359
360static void scarlett_generate_name(int i, char *dst, int offsets[])
361{
362 if (i > offsets[SCARLETT_OFFSET_MIX])
363 sprintf(dst, "Mix %c",
364 'A'+(i - offsets[SCARLETT_OFFSET_MIX] - 1));
365 else if (i > offsets[SCARLETT_OFFSET_ADAT])
366 sprintf(dst, "ADAT %d", i - offsets[SCARLETT_OFFSET_ADAT]);
367 else if (i > offsets[SCARLETT_OFFSET_SPDIF])
368 sprintf(dst, "SPDIF %d", i - offsets[SCARLETT_OFFSET_SPDIF]);
369 else if (i > offsets[SCARLETT_OFFSET_ANALOG])
370 sprintf(dst, "Analog %d", i - offsets[SCARLETT_OFFSET_ANALOG]);
371 else if (i > offsets[SCARLETT_OFFSET_PCM])
372 sprintf(dst, "PCM %d", i - offsets[SCARLETT_OFFSET_PCM]);
373 else
374 sprintf(dst, "Off");
375}
376
377static int scarlett_ctl_enum_dynamic_info(struct snd_kcontrol *kctl,
378 struct snd_ctl_elem_info *uinfo)
379{
380 struct usb_mixer_elem_info *elem = kctl->private_data;
381 struct scarlett_mixer_elem_enum_info *opt = elem->private_data;
382 unsigned int items = opt->len;
383
384 uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
385 uinfo->count = elem->channels;
386 uinfo->value.enumerated.items = items;
387
388 if (uinfo->value.enumerated.item >= items)
389 uinfo->value.enumerated.item = items - 1;
390
391
392 scarlett_generate_name(uinfo->value.enumerated.item,
393 uinfo->value.enumerated.name,
394 opt->offsets);
395
396 return 0;
397}
398
399static int scarlett_ctl_enum_info(struct snd_kcontrol *kctl,
400 struct snd_ctl_elem_info *uinfo)
401{
402 struct usb_mixer_elem_info *elem = kctl->private_data;
403 struct scarlett_mixer_elem_enum_info *opt = elem->private_data;
404
405 return snd_ctl_enum_info(uinfo, elem->channels, opt->len,
406 (const char * const *)opt->names);
407}
408
409static int scarlett_ctl_enum_get(struct snd_kcontrol *kctl,
410 struct snd_ctl_elem_value *ucontrol)
411{
412 struct usb_mixer_elem_info *elem = kctl->private_data;
413 struct scarlett_mixer_elem_enum_info *opt = elem->private_data;
414 int err, val;
415
416 err = snd_usb_get_cur_mix_value(elem, 0, 0, &val);
417 if (err < 0)
418 return err;
419
420 val = clamp(val - opt->start, 0, opt->len-1);
421
422 ucontrol->value.enumerated.item[0] = val;
423
424 return 0;
425}
426
427static int scarlett_ctl_enum_put(struct snd_kcontrol *kctl,
428 struct snd_ctl_elem_value *ucontrol)
429{
430 struct usb_mixer_elem_info *elem = kctl->private_data;
431 struct scarlett_mixer_elem_enum_info *opt = elem->private_data;
432 int err, oval, val;
433
434 err = snd_usb_get_cur_mix_value(elem, 0, 0, &oval);
435 if (err < 0)
436 return err;
437
438 val = ucontrol->value.integer.value[0];
439 val = val + opt->start;
440 if (val != oval) {
441 snd_usb_set_cur_mix_value(elem, 0, 0, val);
442 return 1;
443 }
444 return 0;
445}
446
447static int scarlett_ctl_enum_resume(struct usb_mixer_elem_list *list)
448{
449 struct usb_mixer_elem_info *elem = mixer_elem_list_to_info(list);
450
451 if (elem->cached)
452 snd_usb_set_cur_mix_value(elem, 0, 0, *elem->cache_val);
453 return 0;
454}
455
456static int scarlett_ctl_meter_get(struct snd_kcontrol *kctl,
457 struct snd_ctl_elem_value *ucontrol)
458{
459 struct usb_mixer_elem_info *elem = kctl->private_data;
460 struct snd_usb_audio *chip = elem->head.mixer->chip;
461 unsigned char buf[2 * MAX_CHANNELS] = {0, };
462 int wValue = (elem->control << 8) | elem->idx_off;
463 int idx = snd_usb_ctrl_intf(chip) | (elem->head.id << 8);
464 int err;
465
466 err = snd_usb_ctl_msg(chip->dev,
467 usb_rcvctrlpipe(chip->dev, 0),
468 UAC2_CS_MEM,
469 USB_RECIP_INTERFACE | USB_TYPE_CLASS |
470 USB_DIR_IN, wValue, idx, buf, elem->channels);
471 if (err < 0)
472 return err;
473
474 ucontrol->value.enumerated.item[0] = clamp((int)buf[0], 0, 1);
475 return 0;
476}
477
478static const struct snd_kcontrol_new usb_scarlett_ctl_switch = {
479 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
480 .name = "",
481 .info = scarlett_ctl_switch_info,
482 .get = scarlett_ctl_switch_get,
483 .put = scarlett_ctl_switch_put,
484};
485
486static const DECLARE_TLV_DB_SCALE(db_scale_scarlett_gain, -12800, 100, 0);
487
488static const struct snd_kcontrol_new usb_scarlett_ctl = {
489 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
490 .access = SNDRV_CTL_ELEM_ACCESS_READWRITE |
491 SNDRV_CTL_ELEM_ACCESS_TLV_READ,
492 .name = "",
493 .info = scarlett_ctl_info,
494 .get = scarlett_ctl_get,
495 .put = scarlett_ctl_put,
496 .private_value = 6,
497 .tlv = { .p = db_scale_scarlett_gain }
498};
499
500static const struct snd_kcontrol_new usb_scarlett_ctl_master = {
501 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
502 .access = SNDRV_CTL_ELEM_ACCESS_READWRITE |
503 SNDRV_CTL_ELEM_ACCESS_TLV_READ,
504 .name = "",
505 .info = scarlett_ctl_info,
506 .get = scarlett_ctl_get,
507 .put = scarlett_ctl_put,
508 .private_value = 6,
509 .tlv = { .p = db_scale_scarlett_gain }
510};
511
512static const struct snd_kcontrol_new usb_scarlett_ctl_enum = {
513 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
514 .name = "",
515 .info = scarlett_ctl_enum_info,
516 .get = scarlett_ctl_enum_get,
517 .put = scarlett_ctl_enum_put,
518};
519
520static const struct snd_kcontrol_new usb_scarlett_ctl_dynamic_enum = {
521 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
522 .name = "",
523 .info = scarlett_ctl_enum_dynamic_info,
524 .get = scarlett_ctl_enum_get,
525 .put = scarlett_ctl_enum_put,
526};
527
528static const struct snd_kcontrol_new usb_scarlett_ctl_sync = {
529 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
530 .access = SNDRV_CTL_ELEM_ACCESS_READ | SNDRV_CTL_ELEM_ACCESS_VOLATILE,
531 .name = "",
532 .info = scarlett_ctl_enum_info,
533 .get = scarlett_ctl_meter_get,
534};
535
536static int add_new_ctl(struct usb_mixer_interface *mixer,
537 const struct snd_kcontrol_new *ncontrol,
538 usb_mixer_elem_resume_func_t resume,
539 int index, int offset, int num,
540 int val_type, int channels, const char *name,
541 const struct scarlett_mixer_elem_enum_info *opt,
542 struct usb_mixer_elem_info **elem_ret
543)
544{
545 struct snd_kcontrol *kctl;
546 struct usb_mixer_elem_info *elem;
547 int err;
548
549 elem = kzalloc(sizeof(*elem), GFP_KERNEL);
550 if (!elem)
551 return -ENOMEM;
552
553 elem->head.mixer = mixer;
554 elem->head.resume = resume;
555 elem->control = offset;
556 elem->idx_off = num;
557 elem->head.id = index;
558 elem->val_type = val_type;
559
560 elem->channels = channels;
561
562
563 elem->private_data = (void *)opt;
564
565 kctl = snd_ctl_new1(ncontrol, elem);
566 if (!kctl) {
567 kfree(elem);
568 return -ENOMEM;
569 }
570 kctl->private_free = snd_usb_mixer_elem_free;
571
572 strlcpy(kctl->id.name, name, sizeof(kctl->id.name));
573
574 err = snd_usb_mixer_add_control(&elem->head, kctl);
575 if (err < 0)
576 return err;
577
578 if (elem_ret)
579 *elem_ret = elem;
580
581 return 0;
582}
583
584static int add_output_ctls(struct usb_mixer_interface *mixer,
585 int index, const char *name,
586 const struct scarlett_device_info *info)
587{
588 int err;
589 char mx[SNDRV_CTL_ELEM_ID_NAME_MAXLEN];
590 struct usb_mixer_elem_info *elem;
591
592
593 snprintf(mx, sizeof(mx), "Master %d (%s) Playback Switch",
594 index + 1, name);
595 err = add_new_ctl(mixer, &usb_scarlett_ctl_switch,
596 scarlett_ctl_resume, 0x0a, 0x01,
597 2*index+1, USB_MIXER_S16, 2, mx, NULL, &elem);
598 if (err < 0)
599 return err;
600
601
602 snprintf(mx, sizeof(mx), "Master %d (%s) Playback Volume",
603 index + 1, name);
604 err = add_new_ctl(mixer, &usb_scarlett_ctl_master,
605 scarlett_ctl_resume, 0x0a, 0x02,
606 2*index+1, USB_MIXER_S16, 2, mx, NULL, &elem);
607 if (err < 0)
608 return err;
609
610
611 snprintf(mx, sizeof(mx), "Master %dL (%s) Source Playback Enum",
612 index + 1, name);
613 err = add_new_ctl(mixer, &usb_scarlett_ctl_dynamic_enum,
614 scarlett_ctl_enum_resume, 0x33, 0x00,
615 2*index, USB_MIXER_S16, 1, mx, &info->opt_master,
616 &elem);
617 if (err < 0)
618 return err;
619
620
621 snprintf(mx, sizeof(mx), "Master %dR (%s) Source Playback Enum",
622 index + 1, name);
623 err = add_new_ctl(mixer, &usb_scarlett_ctl_dynamic_enum,
624 scarlett_ctl_enum_resume, 0x33, 0x00,
625 2*index+1, USB_MIXER_S16, 1, mx, &info->opt_master,
626 &elem);
627 if (err < 0)
628 return err;
629
630 return 0;
631}
632
633
634
635
636static struct scarlett_device_info s6i6_info = {
637 .matrix_in = 18,
638 .matrix_out = 8,
639 .input_len = 6,
640 .output_len = 6,
641
642 .opt_master = {
643 .start = -1,
644 .len = 27,
645 .offsets = {0, 12, 16, 18, 18},
646 .names = NULL
647 },
648
649 .opt_matrix = {
650 .start = -1,
651 .len = 19,
652 .offsets = {0, 12, 16, 18, 18},
653 .names = NULL
654 },
655
656 .num_controls = 9,
657 .controls = {
658 { .num = 0, .type = SCARLETT_OUTPUTS, .name = "Monitor" },
659 { .num = 1, .type = SCARLETT_OUTPUTS, .name = "Headphone" },
660 { .num = 2, .type = SCARLETT_OUTPUTS, .name = "SPDIF" },
661 { .num = 1, .type = SCARLETT_SWITCH_IMPEDANCE, .name = NULL},
662 { .num = 1, .type = SCARLETT_SWITCH_PAD, .name = NULL},
663 { .num = 2, .type = SCARLETT_SWITCH_IMPEDANCE, .name = NULL},
664 { .num = 2, .type = SCARLETT_SWITCH_PAD, .name = NULL},
665 { .num = 3, .type = SCARLETT_SWITCH_PAD, .name = NULL},
666 { .num = 4, .type = SCARLETT_SWITCH_PAD, .name = NULL},
667 },
668
669 .matrix_mux_init = {
670 12, 13, 14, 15,
671 16, 17,
672 0, 1, 2, 3, 4, 5, 6, 7,
673 8, 9, 10, 11
674 }
675};
676
677
678static struct scarlett_device_info s8i6_info = {
679 .matrix_in = 18,
680 .matrix_out = 6,
681 .input_len = 8,
682 .output_len = 6,
683
684 .opt_master = {
685 .start = -1,
686 .len = 25,
687 .offsets = {0, 12, 16, 18, 18},
688 .names = NULL
689 },
690
691 .opt_matrix = {
692 .start = -1,
693 .len = 19,
694 .offsets = {0, 12, 16, 18, 18},
695 .names = NULL
696 },
697
698 .num_controls = 7,
699 .controls = {
700 { .num = 0, .type = SCARLETT_OUTPUTS, .name = "Monitor" },
701 { .num = 1, .type = SCARLETT_OUTPUTS, .name = "Headphone" },
702 { .num = 2, .type = SCARLETT_OUTPUTS, .name = "SPDIF" },
703 { .num = 1, .type = SCARLETT_SWITCH_IMPEDANCE, .name = NULL},
704 { .num = 2, .type = SCARLETT_SWITCH_IMPEDANCE, .name = NULL},
705 { .num = 3, .type = SCARLETT_SWITCH_PAD, .name = NULL},
706 { .num = 4, .type = SCARLETT_SWITCH_PAD, .name = NULL},
707 },
708
709 .matrix_mux_init = {
710 12, 13, 14, 15,
711 16, 17,
712 0, 1, 2, 3, 4, 5, 6, 7,
713 8, 9, 10, 11
714 }
715};
716
717static struct scarlett_device_info s18i6_info = {
718 .matrix_in = 18,
719 .matrix_out = 6,
720 .input_len = 18,
721 .output_len = 6,
722
723 .opt_master = {
724 .start = -1,
725 .len = 31,
726 .offsets = {0, 6, 14, 16, 24},
727 .names = NULL,
728 },
729
730 .opt_matrix = {
731 .start = -1,
732 .len = 25,
733 .offsets = {0, 6, 14, 16, 24},
734 .names = NULL,
735 },
736
737 .num_controls = 5,
738 .controls = {
739 { .num = 0, .type = SCARLETT_OUTPUTS, .name = "Monitor" },
740 { .num = 1, .type = SCARLETT_OUTPUTS, .name = "Headphone" },
741 { .num = 2, .type = SCARLETT_OUTPUTS, .name = "SPDIF" },
742 { .num = 1, .type = SCARLETT_SWITCH_IMPEDANCE, .name = NULL},
743 { .num = 2, .type = SCARLETT_SWITCH_IMPEDANCE, .name = NULL},
744 },
745
746 .matrix_mux_init = {
747 6, 7, 8, 9, 10, 11, 12, 13,
748 16, 17, 18, 19, 20, 21,
749 14, 15,
750 0, 1
751 }
752};
753
754static struct scarlett_device_info s18i8_info = {
755 .matrix_in = 18,
756 .matrix_out = 8,
757 .input_len = 18,
758 .output_len = 8,
759
760 .opt_master = {
761 .start = -1,
762 .len = 35,
763 .offsets = {0, 8, 16, 18, 26},
764 .names = NULL
765 },
766
767 .opt_matrix = {
768 .start = -1,
769 .len = 27,
770 .offsets = {0, 8, 16, 18, 26},
771 .names = NULL
772 },
773
774 .num_controls = 10,
775 .controls = {
776 { .num = 0, .type = SCARLETT_OUTPUTS, .name = "Monitor" },
777 { .num = 1, .type = SCARLETT_OUTPUTS, .name = "Headphone 1" },
778 { .num = 2, .type = SCARLETT_OUTPUTS, .name = "Headphone 2" },
779 { .num = 3, .type = SCARLETT_OUTPUTS, .name = "SPDIF" },
780 { .num = 1, .type = SCARLETT_SWITCH_IMPEDANCE, .name = NULL},
781 { .num = 1, .type = SCARLETT_SWITCH_PAD, .name = NULL},
782 { .num = 2, .type = SCARLETT_SWITCH_IMPEDANCE, .name = NULL},
783 { .num = 2, .type = SCARLETT_SWITCH_PAD, .name = NULL},
784 { .num = 3, .type = SCARLETT_SWITCH_PAD, .name = NULL},
785 { .num = 4, .type = SCARLETT_SWITCH_PAD, .name = NULL},
786 },
787
788 .matrix_mux_init = {
789 8, 9, 10, 11, 12, 13, 14, 15,
790 18, 19, 20, 21, 22, 23,
791 16, 17,
792 0, 1
793 }
794};
795
796static struct scarlett_device_info s18i20_info = {
797 .matrix_in = 18,
798 .matrix_out = 8,
799 .input_len = 18,
800 .output_len = 20,
801
802 .opt_master = {
803 .start = -1,
804 .len = 47,
805 .offsets = {0, 20, 28, 30, 38},
806 .names = NULL
807 },
808
809 .opt_matrix = {
810 .start = -1,
811 .len = 39,
812 .offsets = {0, 20, 28, 30, 38},
813 .names = NULL
814 },
815
816 .num_controls = 10,
817 .controls = {
818 { .num = 0, .type = SCARLETT_OUTPUTS, .name = "Monitor" },
819 { .num = 1, .type = SCARLETT_OUTPUTS, .name = "Line 3/4" },
820 { .num = 2, .type = SCARLETT_OUTPUTS, .name = "Line 5/6" },
821 { .num = 3, .type = SCARLETT_OUTPUTS, .name = "Line 7/8" },
822 { .num = 4, .type = SCARLETT_OUTPUTS, .name = "Line 9/10" },
823 { .num = 5, .type = SCARLETT_OUTPUTS, .name = "SPDIF" },
824 { .num = 6, .type = SCARLETT_OUTPUTS, .name = "ADAT 1/2" },
825 { .num = 7, .type = SCARLETT_OUTPUTS, .name = "ADAT 3/4" },
826 { .num = 8, .type = SCARLETT_OUTPUTS, .name = "ADAT 5/6" },
827 { .num = 9, .type = SCARLETT_OUTPUTS, .name = "ADAT 7/8" },
828
829
830
831
832
833
834 },
835
836 .matrix_mux_init = {
837 20, 21, 22, 23, 24, 25, 26, 27,
838 30, 31, 32, 33, 34, 35,
839 28, 29,
840 0, 1
841 }
842};
843
844
845static int scarlett_controls_create_generic(struct usb_mixer_interface *mixer,
846 struct scarlett_device_info *info)
847{
848 int i, err;
849 char mx[SNDRV_CTL_ELEM_ID_NAME_MAXLEN];
850 const struct scarlett_mixer_control *ctl;
851 struct usb_mixer_elem_info *elem;
852
853
854 err = add_new_ctl(mixer, &usb_scarlett_ctl_switch,
855 scarlett_ctl_resume, 0x0a, 0x01, 0,
856 USB_MIXER_S16, 1, "Master Playback Switch", NULL,
857 &elem);
858 if (err < 0)
859 return err;
860
861 err = add_new_ctl(mixer, &usb_scarlett_ctl_master,
862 scarlett_ctl_resume, 0x0a, 0x02, 0,
863 USB_MIXER_S16, 1, "Master Playback Volume", NULL,
864 &elem);
865 if (err < 0)
866 return err;
867
868
869 for (i = 0; i < info->num_controls; i++) {
870 ctl = &info->controls[i];
871
872 switch (ctl->type) {
873 case SCARLETT_OUTPUTS:
874 err = add_output_ctls(mixer, ctl->num, ctl->name, info);
875 if (err < 0)
876 return err;
877 break;
878 case SCARLETT_SWITCH_IMPEDANCE:
879 sprintf(mx, "Input %d Impedance Switch", ctl->num);
880 err = add_new_ctl(mixer, &usb_scarlett_ctl_enum,
881 scarlett_ctl_enum_resume, 0x01,
882 0x09, ctl->num, USB_MIXER_S16, 1, mx,
883 &opt_impedance, &elem);
884 if (err < 0)
885 return err;
886 break;
887 case SCARLETT_SWITCH_PAD:
888 sprintf(mx, "Input %d Pad Switch", ctl->num);
889 err = add_new_ctl(mixer, &usb_scarlett_ctl_enum,
890 scarlett_ctl_enum_resume, 0x01,
891 0x0b, ctl->num, USB_MIXER_S16, 1, mx,
892 &opt_pad, &elem);
893 if (err < 0)
894 return err;
895 break;
896 }
897 }
898
899 return 0;
900}
901
902
903
904
905int snd_scarlett_controls_create(struct usb_mixer_interface *mixer)
906{
907 int err, i, o;
908 char mx[SNDRV_CTL_ELEM_ID_NAME_MAXLEN];
909 struct scarlett_device_info *info;
910 struct usb_mixer_elem_info *elem;
911 static char sample_rate_buffer[4] = { '\x80', '\xbb', '\x00', '\x00' };
912
913
914 if (!mixer->protocol)
915 return 0;
916
917 switch (mixer->chip->usb_id) {
918 case USB_ID(0x1235, 0x8012):
919 info = &s6i6_info;
920 break;
921 case USB_ID(0x1235, 0x8002):
922 info = &s8i6_info;
923 break;
924 case USB_ID(0x1235, 0x8004):
925 info = &s18i6_info;
926 break;
927 case USB_ID(0x1235, 0x8014):
928 info = &s18i8_info;
929 break;
930 case USB_ID(0x1235, 0x800c):
931 info = &s18i20_info;
932 break;
933 default:
934 return -EINVAL;
935 }
936
937
938 err = scarlett_controls_create_generic(mixer, info);
939 if (err < 0)
940 return err;
941
942
943 for (i = 0; i < info->matrix_in; i++) {
944 snprintf(mx, sizeof(mx), "Matrix %02d Input Playback Route",
945 i+1);
946 err = add_new_ctl(mixer, &usb_scarlett_ctl_dynamic_enum,
947 scarlett_ctl_enum_resume, 0x32,
948 0x06, i, USB_MIXER_S16, 1, mx,
949 &info->opt_matrix, &elem);
950 if (err < 0)
951 return err;
952
953 for (o = 0; o < info->matrix_out; o++) {
954 sprintf(mx, "Matrix %02d Mix %c Playback Volume", i+1,
955 o+'A');
956 err = add_new_ctl(mixer, &usb_scarlett_ctl,
957 scarlett_ctl_resume, 0x3c, 0x00,
958 (i << 3) + (o & 0x07), USB_MIXER_S16,
959 1, mx, NULL, &elem);
960 if (err < 0)
961 return err;
962
963 }
964 }
965
966 for (i = 0; i < info->input_len; i++) {
967 snprintf(mx, sizeof(mx), "Input Source %02d Capture Route",
968 i+1);
969 err = add_new_ctl(mixer, &usb_scarlett_ctl_dynamic_enum,
970 scarlett_ctl_enum_resume, 0x34,
971 0x00, i, USB_MIXER_S16, 1, mx,
972 &info->opt_master, &elem);
973 if (err < 0)
974 return err;
975 }
976
977
978 err = add_new_ctl(mixer, &usb_scarlett_ctl_enum,
979 scarlett_ctl_enum_resume, 0x28, 0x01, 0,
980 USB_MIXER_U8, 1, "Sample Clock Source",
981 &opt_clock, &elem);
982 if (err < 0)
983 return err;
984
985
986 err = add_new_ctl(mixer, &usb_scarlett_ctl_sync, NULL, 0x3c, 0x00, 2,
987 USB_MIXER_U8, 1, "Sample Clock Sync Status",
988 &opt_sync, &elem);
989 if (err < 0)
990 return err;
991
992
993 err = snd_usb_ctl_msg(mixer->chip->dev,
994 usb_sndctrlpipe(mixer->chip->dev, 0), UAC2_CS_CUR,
995 USB_RECIP_INTERFACE | USB_TYPE_CLASS |
996 USB_DIR_OUT, 0x0100, snd_usb_ctrl_intf(mixer->chip) |
997 (0x29 << 8), sample_rate_buffer, 4);
998 if (err < 0)
999 return err;
1000
1001 return err;
1002}
1003