Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
torvalds
GitHub Repository: torvalds/linux
Path: blob/master/sound/usb/mixer_scarlett.c
26378 views
1
// SPDX-License-Identifier: GPL-2.0-or-later
2
/*
3
* Scarlett Driver for ALSA
4
*
5
* Copyright (c) 2013 by Tobias Hoffmann
6
* Copyright (c) 2013 by Robin Gareus <robin at gareus.org>
7
* Copyright (c) 2002 by Takashi Iwai <tiwai at suse.de>
8
* Copyright (c) 2014 by Chris J Arges <chris.j.arges at canonical.com>
9
*
10
* Many codes borrowed from audio.c by
11
* Alan Cox (alan at lxorguk.ukuu.org.uk)
12
* Thomas Sailer (sailer at ife.ee.ethz.ch)
13
*
14
* Code cleanup:
15
* David Henningsson <david.henningsson at canonical.com>
16
*/
17
18
/*
19
* Rewritten and extended to support more models, e.g. Scarlett 18i8.
20
*
21
* Auto-detection via UAC2 is not feasible to properly discover the vast
22
* majority of features. It's related to both Linux/ALSA's UAC2 as well as
23
* Focusrite's implementation of it. Eventually quirks may be sufficient but
24
* right now it's a major headache to work around these things.
25
*
26
* NB. Neither the OSX nor the win driver provided by Focusrite performs
27
* discovery, they seem to operate the same as this driver.
28
*/
29
30
/* Mixer Interface for the Focusrite Scarlett 18i6 audio interface.
31
*
32
* The protocol was reverse engineered by looking at communication between
33
* Scarlett MixControl (v 1.2.128.0) and the Focusrite(R) Scarlett 18i6
34
* (firmware v305) using wireshark and usbmon in January 2013.
35
* Extended in July 2013.
36
*
37
* this mixer gives complete access to all features of the device:
38
* - change Impedance of inputs (Line-in, Mic / Instrument, Hi-Z)
39
* - select clock source
40
* - dynamic input to mixer-matrix assignment
41
* - 18 x 6 mixer-matrix gain stages
42
* - bus routing & volume control
43
* - automatic re-initialization on connect if device was power-cycled
44
*
45
* USB URB commands overview (bRequest = 0x01 = UAC2_CS_CUR)
46
* wIndex
47
* 0x01 Analog Input line/instrument impedance switch, wValue=0x0901 +
48
* channel, data=Line/Inst (2bytes)
49
* pad (-10dB) switch, wValue=0x0b01 + channel, data=Off/On (2bytes)
50
* ?? wValue=0x0803/04, ?? (2bytes)
51
* 0x0a Master Volume, wValue=0x0200+bus[0:all + only 1..4?] data(2bytes)
52
* Bus Mute/Unmute wValue=0x0100+bus[0:all + only 1..4?], data(2bytes)
53
* 0x28 Clock source, wValue=0x0100, data={1:int,2:spdif,3:adat} (1byte)
54
* 0x29 Set Sample-rate, wValue=0x0100, data=sample-rate(4bytes)
55
* 0x32 Mixer mux, wValue=0x0600 + mixer-channel, data=input-to-connect(2bytes)
56
* 0x33 Output mux, wValue=bus, data=input-to-connect(2bytes)
57
* 0x34 Capture mux, wValue=0...18, data=input-to-connect(2bytes)
58
* 0x3c Matrix Mixer gains, wValue=mixer-node data=gain(2bytes)
59
* ?? [sometimes](4bytes, e.g 0x000003be 0x000003bf ...03ff)
60
*
61
* USB reads: (i.e. actually issued by original software)
62
* 0x01 wValue=0x0901+channel (1byte!!), wValue=0x0b01+channed (1byte!!)
63
* 0x29 wValue=0x0100 sample-rate(4bytes)
64
* wValue=0x0200 ?? 1byte (only once)
65
* 0x2a wValue=0x0100 ?? 4bytes, sample-rate2 ??
66
*
67
* USB reads with bRequest = 0x03 = UAC2_CS_MEM
68
* 0x3c wValue=0x0002 1byte: sync status (locked=1)
69
* wValue=0x0000 18*2byte: peak meter (inputs)
70
* wValue=0x0001 8(?)*2byte: peak meter (mix)
71
* wValue=0x0003 6*2byte: peak meter (pcm/daw)
72
*
73
* USB write with bRequest = 0x03
74
* 0x3c Save settings to hardware: wValue=0x005a, data=0xa5
75
*
76
*
77
* <ditaa>
78
* /--------------\ 18chn 6chn /--------------\
79
* | Hardware in +--+-------\ /------+--+ ALSA PCM out |
80
* \--------------/ | | | | \--------------/
81
* | | | |
82
* | v v |
83
* | +---------------+ |
84
* | \ Matrix Mux / |
85
* | +-----+-----+ |
86
* | | |
87
* | | 18chn |
88
* | v |
89
* | +-----------+ |
90
* | | Mixer | |
91
* | | Matrix | |
92
* | | | |
93
* | | 18x6 Gain | |
94
* | | stages | |
95
* | +-----+-----+ |
96
* | | |
97
* | | |
98
* | 18chn | 6chn | 6chn
99
* v v v
100
* =========================
101
* +---------------+ +--—------------+
102
* \ Output Mux / \ Capture Mux /
103
* +-----+-----+ +-----+-----+
104
* | |
105
* | 6chn |
106
* v |
107
* +-------------+ |
108
* | Master Gain | |
109
* +------+------+ |
110
* | |
111
* | 6chn | 18chn
112
* | (3 stereo pairs) |
113
* /--------------\ | | /--------------\
114
* | Hardware out |<--/ \-->| ALSA PCM in |
115
* \--------------/ \--------------/
116
* </ditaa>
117
*
118
*/
119
120
#include <linux/slab.h>
121
#include <linux/usb.h>
122
#include <linux/usb/audio-v2.h>
123
124
#include <sound/core.h>
125
#include <sound/control.h>
126
#include <sound/tlv.h>
127
128
#include "usbaudio.h"
129
#include "mixer.h"
130
#include "helper.h"
131
#include "power.h"
132
133
#include "mixer_scarlett.h"
134
135
/* some gui mixers can't handle negative ctl values */
136
#define SND_SCARLETT_LEVEL_BIAS 128
137
#define SND_SCARLETT_MATRIX_IN_MAX 18
138
#define SND_SCARLETT_CONTROLS_MAX 10
139
#define SND_SCARLETT_OFFSETS_MAX 5
140
141
enum {
142
SCARLETT_OUTPUTS,
143
SCARLETT_SWITCH_IMPEDANCE,
144
SCARLETT_SWITCH_PAD,
145
SCARLETT_SWITCH_GAIN,
146
};
147
148
enum {
149
SCARLETT_OFFSET_PCM = 0,
150
SCARLETT_OFFSET_ANALOG = 1,
151
SCARLETT_OFFSET_SPDIF = 2,
152
SCARLETT_OFFSET_ADAT = 3,
153
SCARLETT_OFFSET_MIX = 4,
154
};
155
156
struct scarlett_mixer_elem_enum_info {
157
int start;
158
int len;
159
int offsets[SND_SCARLETT_OFFSETS_MAX];
160
char const * const *names;
161
};
162
163
struct scarlett_mixer_control {
164
unsigned char num;
165
unsigned char type;
166
const char *name;
167
};
168
169
struct scarlett_device_info {
170
int matrix_in;
171
int matrix_out;
172
int input_len;
173
int output_len;
174
175
struct scarlett_mixer_elem_enum_info opt_master;
176
struct scarlett_mixer_elem_enum_info opt_matrix;
177
178
/* initial values for matrix mux */
179
int matrix_mux_init[SND_SCARLETT_MATRIX_IN_MAX];
180
181
int num_controls; /* number of items in controls */
182
const struct scarlett_mixer_control controls[SND_SCARLETT_CONTROLS_MAX];
183
};
184
185
/********************** Enum Strings *************************/
186
187
static const struct scarlett_mixer_elem_enum_info opt_pad = {
188
.start = 0,
189
.len = 2,
190
.offsets = {},
191
.names = (char const * const []){
192
"0dB", "-10dB"
193
}
194
};
195
196
static const struct scarlett_mixer_elem_enum_info opt_gain = {
197
.start = 0,
198
.len = 2,
199
.offsets = {},
200
.names = (char const * const []){
201
"Lo", "Hi"
202
}
203
};
204
205
static 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
214
static 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
223
static 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
232
static 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
244
static 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; /* invert mute logic for mixer */
256
ucontrol->value.integer.value[i] = val;
257
}
258
259
return 0;
260
}
261
262
static 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
288
static 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
300
static 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
314
static 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
333
static 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
360
static void scarlett_generate_name(int i, char *dst, size_t size, int offsets[])
361
{
362
if (i > offsets[SCARLETT_OFFSET_MIX])
363
scnprintf(dst, size, "Mix %c",
364
'A'+(i - offsets[SCARLETT_OFFSET_MIX] - 1));
365
else if (i > offsets[SCARLETT_OFFSET_ADAT])
366
scnprintf(dst, size, "ADAT %d", i - offsets[SCARLETT_OFFSET_ADAT]);
367
else if (i > offsets[SCARLETT_OFFSET_SPDIF])
368
scnprintf(dst, size, "SPDIF %d", i - offsets[SCARLETT_OFFSET_SPDIF]);
369
else if (i > offsets[SCARLETT_OFFSET_ANALOG])
370
scnprintf(dst, size, "Analog %d", i - offsets[SCARLETT_OFFSET_ANALOG]);
371
else if (i > offsets[SCARLETT_OFFSET_PCM])
372
scnprintf(dst, size, "PCM %d", i - offsets[SCARLETT_OFFSET_PCM]);
373
else
374
scnprintf(dst, size, "Off");
375
}
376
377
static 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
/* generate name dynamically based on item number and offset info */
392
scarlett_generate_name(uinfo->value.enumerated.item,
393
uinfo->value.enumerated.name,
394
sizeof(uinfo->value.enumerated.name),
395
opt->offsets);
396
397
return 0;
398
}
399
400
static 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
410
static 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
428
static 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
448
static int scarlett_ctl_enum_resume(struct usb_mixer_elem_list *list)
449
{
450
struct usb_mixer_elem_info *elem = mixer_elem_list_to_info(list);
451
452
if (elem->cached)
453
snd_usb_set_cur_mix_value(elem, 0, 0, *elem->cache_val);
454
return 0;
455
}
456
457
static int scarlett_ctl_meter_get(struct snd_kcontrol *kctl,
458
struct snd_ctl_elem_value *ucontrol)
459
{
460
struct usb_mixer_elem_info *elem = kctl->private_data;
461
struct snd_usb_audio *chip = elem->head.mixer->chip;
462
unsigned char buf[2 * MAX_CHANNELS] = {0, };
463
int wValue = (elem->control << 8) | elem->idx_off;
464
int idx = snd_usb_ctrl_intf(elem->head.mixer->hostif) | (elem->head.id << 8);
465
int err;
466
467
err = snd_usb_ctl_msg(chip->dev,
468
usb_rcvctrlpipe(chip->dev, 0),
469
UAC2_CS_MEM,
470
USB_RECIP_INTERFACE | USB_TYPE_CLASS |
471
USB_DIR_IN, wValue, idx, buf, elem->channels);
472
if (err < 0)
473
return err;
474
475
ucontrol->value.enumerated.item[0] = clamp((int)buf[0], 0, 1);
476
return 0;
477
}
478
479
static const struct snd_kcontrol_new usb_scarlett_ctl_switch = {
480
.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
481
.name = "",
482
.info = scarlett_ctl_switch_info,
483
.get = scarlett_ctl_switch_get,
484
.put = scarlett_ctl_switch_put,
485
};
486
487
static const DECLARE_TLV_DB_SCALE(db_scale_scarlett_gain, -12800, 100, 0);
488
489
static const struct snd_kcontrol_new usb_scarlett_ctl = {
490
.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
491
.access = SNDRV_CTL_ELEM_ACCESS_READWRITE |
492
SNDRV_CTL_ELEM_ACCESS_TLV_READ,
493
.name = "",
494
.info = scarlett_ctl_info,
495
.get = scarlett_ctl_get,
496
.put = scarlett_ctl_put,
497
.private_value = 6, /* max value */
498
.tlv = { .p = db_scale_scarlett_gain }
499
};
500
501
static const struct snd_kcontrol_new usb_scarlett_ctl_master = {
502
.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
503
.access = SNDRV_CTL_ELEM_ACCESS_READWRITE |
504
SNDRV_CTL_ELEM_ACCESS_TLV_READ,
505
.name = "",
506
.info = scarlett_ctl_info,
507
.get = scarlett_ctl_get,
508
.put = scarlett_ctl_put,
509
.private_value = 6, /* max value */
510
.tlv = { .p = db_scale_scarlett_gain }
511
};
512
513
static const struct snd_kcontrol_new usb_scarlett_ctl_enum = {
514
.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
515
.name = "",
516
.info = scarlett_ctl_enum_info,
517
.get = scarlett_ctl_enum_get,
518
.put = scarlett_ctl_enum_put,
519
};
520
521
static const struct snd_kcontrol_new usb_scarlett_ctl_dynamic_enum = {
522
.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
523
.name = "",
524
.info = scarlett_ctl_enum_dynamic_info,
525
.get = scarlett_ctl_enum_get,
526
.put = scarlett_ctl_enum_put,
527
};
528
529
static const struct snd_kcontrol_new usb_scarlett_ctl_sync = {
530
.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
531
.access = SNDRV_CTL_ELEM_ACCESS_READ | SNDRV_CTL_ELEM_ACCESS_VOLATILE,
532
.name = "",
533
.info = scarlett_ctl_enum_info,
534
.get = scarlett_ctl_meter_get,
535
};
536
537
static int add_new_ctl(struct usb_mixer_interface *mixer,
538
const struct snd_kcontrol_new *ncontrol,
539
usb_mixer_elem_resume_func_t resume,
540
int index, int offset, int num,
541
int val_type, int channels, const char *name,
542
const struct scarlett_mixer_elem_enum_info *opt,
543
struct usb_mixer_elem_info **elem_ret
544
)
545
{
546
struct snd_kcontrol *kctl;
547
struct usb_mixer_elem_info *elem;
548
int err;
549
550
elem = kzalloc(sizeof(*elem), GFP_KERNEL);
551
if (!elem)
552
return -ENOMEM;
553
554
elem->head.mixer = mixer;
555
elem->head.resume = resume;
556
elem->control = offset;
557
elem->idx_off = num;
558
elem->head.id = index;
559
elem->val_type = val_type;
560
561
elem->channels = channels;
562
563
/* add scarlett_mixer_elem_enum_info struct */
564
elem->private_data = (void *)opt;
565
566
kctl = snd_ctl_new1(ncontrol, elem);
567
if (!kctl) {
568
kfree(elem);
569
return -ENOMEM;
570
}
571
kctl->private_free = snd_usb_mixer_elem_free;
572
573
strscpy(kctl->id.name, name, sizeof(kctl->id.name));
574
575
err = snd_usb_mixer_add_control(&elem->head, kctl);
576
if (err < 0)
577
return err;
578
579
if (elem_ret)
580
*elem_ret = elem;
581
582
return 0;
583
}
584
585
static int add_output_ctls(struct usb_mixer_interface *mixer,
586
int index, const char *name,
587
const struct scarlett_device_info *info)
588
{
589
int err;
590
char mx[SNDRV_CTL_ELEM_ID_NAME_MAXLEN];
591
struct usb_mixer_elem_info *elem;
592
593
/* Add mute switch */
594
snprintf(mx, sizeof(mx), "Master %d (%s) Playback Switch",
595
index + 1, name);
596
err = add_new_ctl(mixer, &usb_scarlett_ctl_switch,
597
scarlett_ctl_resume, 0x0a, 0x01,
598
2*index+1, USB_MIXER_S16, 2, mx, NULL, &elem);
599
if (err < 0)
600
return err;
601
602
/* Add volume control and initialize to 0 */
603
snprintf(mx, sizeof(mx), "Master %d (%s) Playback Volume",
604
index + 1, name);
605
err = add_new_ctl(mixer, &usb_scarlett_ctl_master,
606
scarlett_ctl_resume, 0x0a, 0x02,
607
2*index+1, USB_MIXER_S16, 2, mx, NULL, &elem);
608
if (err < 0)
609
return err;
610
611
/* Add L channel source playback enumeration */
612
snprintf(mx, sizeof(mx), "Master %dL (%s) Source Playback Enum",
613
index + 1, name);
614
err = add_new_ctl(mixer, &usb_scarlett_ctl_dynamic_enum,
615
scarlett_ctl_enum_resume, 0x33, 0x00,
616
2*index, USB_MIXER_S16, 1, mx, &info->opt_master,
617
&elem);
618
if (err < 0)
619
return err;
620
621
/* Add R channel source playback enumeration */
622
snprintf(mx, sizeof(mx), "Master %dR (%s) Source Playback Enum",
623
index + 1, name);
624
err = add_new_ctl(mixer, &usb_scarlett_ctl_dynamic_enum,
625
scarlett_ctl_enum_resume, 0x33, 0x00,
626
2*index+1, USB_MIXER_S16, 1, mx, &info->opt_master,
627
&elem);
628
if (err < 0)
629
return err;
630
631
return 0;
632
}
633
634
/********************** device-specific config *************************/
635
636
/* untested... */
637
static const struct scarlett_device_info s6i6_info = {
638
.matrix_in = 18,
639
.matrix_out = 8,
640
.input_len = 6,
641
.output_len = 6,
642
643
.opt_master = {
644
.start = -1,
645
.len = 27,
646
.offsets = {0, 12, 16, 18, 18},
647
.names = NULL
648
},
649
650
.opt_matrix = {
651
.start = -1,
652
.len = 19,
653
.offsets = {0, 12, 16, 18, 18},
654
.names = NULL
655
},
656
657
.num_controls = 9,
658
.controls = {
659
{ .num = 0, .type = SCARLETT_OUTPUTS, .name = "Monitor" },
660
{ .num = 1, .type = SCARLETT_OUTPUTS, .name = "Headphone" },
661
{ .num = 2, .type = SCARLETT_OUTPUTS, .name = "SPDIF" },
662
{ .num = 1, .type = SCARLETT_SWITCH_IMPEDANCE, .name = NULL},
663
{ .num = 1, .type = SCARLETT_SWITCH_PAD, .name = NULL},
664
{ .num = 2, .type = SCARLETT_SWITCH_IMPEDANCE, .name = NULL},
665
{ .num = 2, .type = SCARLETT_SWITCH_PAD, .name = NULL},
666
{ .num = 3, .type = SCARLETT_SWITCH_GAIN, .name = NULL},
667
{ .num = 4, .type = SCARLETT_SWITCH_GAIN, .name = NULL},
668
},
669
670
.matrix_mux_init = {
671
12, 13, 14, 15, /* Analog -> 1..4 */
672
16, 17, /* SPDIF -> 5,6 */
673
0, 1, 2, 3, 4, 5, 6, 7, /* PCM[1..12] -> 7..18 */
674
8, 9, 10, 11
675
}
676
};
677
678
/* untested... */
679
static const struct scarlett_device_info s8i6_info = {
680
.matrix_in = 18,
681
.matrix_out = 6,
682
.input_len = 8,
683
.output_len = 6,
684
685
.opt_master = {
686
.start = -1,
687
.len = 25,
688
.offsets = {0, 12, 16, 18, 18},
689
.names = NULL
690
},
691
692
.opt_matrix = {
693
.start = -1,
694
.len = 19,
695
.offsets = {0, 12, 16, 18, 18},
696
.names = NULL
697
},
698
699
.num_controls = 7,
700
.controls = {
701
{ .num = 0, .type = SCARLETT_OUTPUTS, .name = "Monitor" },
702
{ .num = 1, .type = SCARLETT_OUTPUTS, .name = "Headphone" },
703
{ .num = 2, .type = SCARLETT_OUTPUTS, .name = "SPDIF" },
704
{ .num = 1, .type = SCARLETT_SWITCH_IMPEDANCE, .name = NULL},
705
{ .num = 2, .type = SCARLETT_SWITCH_IMPEDANCE, .name = NULL},
706
{ .num = 3, .type = SCARLETT_SWITCH_PAD, .name = NULL},
707
{ .num = 4, .type = SCARLETT_SWITCH_PAD, .name = NULL},
708
},
709
710
.matrix_mux_init = {
711
12, 13, 14, 15, /* Analog -> 1..4 */
712
16, 17, /* SPDIF -> 5,6 */
713
0, 1, 2, 3, 4, 5, 6, 7, /* PCM[1..12] -> 7..18 */
714
8, 9, 10, 11
715
}
716
};
717
718
static const struct scarlett_device_info s18i6_info = {
719
.matrix_in = 18,
720
.matrix_out = 6,
721
.input_len = 18,
722
.output_len = 6,
723
724
.opt_master = {
725
.start = -1,
726
.len = 31,
727
.offsets = {0, 6, 14, 16, 24},
728
.names = NULL,
729
},
730
731
.opt_matrix = {
732
.start = -1,
733
.len = 25,
734
.offsets = {0, 6, 14, 16, 24},
735
.names = NULL,
736
},
737
738
.num_controls = 5,
739
.controls = {
740
{ .num = 0, .type = SCARLETT_OUTPUTS, .name = "Monitor" },
741
{ .num = 1, .type = SCARLETT_OUTPUTS, .name = "Headphone" },
742
{ .num = 2, .type = SCARLETT_OUTPUTS, .name = "SPDIF" },
743
{ .num = 1, .type = SCARLETT_SWITCH_IMPEDANCE, .name = NULL},
744
{ .num = 2, .type = SCARLETT_SWITCH_IMPEDANCE, .name = NULL},
745
},
746
747
.matrix_mux_init = {
748
6, 7, 8, 9, 10, 11, 12, 13, /* Analog -> 1..8 */
749
16, 17, 18, 19, 20, 21, /* ADAT[1..6] -> 9..14 */
750
14, 15, /* SPDIF -> 15,16 */
751
0, 1 /* PCM[1,2] -> 17,18 */
752
}
753
};
754
755
static const struct scarlett_device_info s18i8_info = {
756
.matrix_in = 18,
757
.matrix_out = 8,
758
.input_len = 18,
759
.output_len = 8,
760
761
.opt_master = {
762
.start = -1,
763
.len = 35,
764
.offsets = {0, 8, 16, 18, 26},
765
.names = NULL
766
},
767
768
.opt_matrix = {
769
.start = -1,
770
.len = 27,
771
.offsets = {0, 8, 16, 18, 26},
772
.names = NULL
773
},
774
775
.num_controls = 10,
776
.controls = {
777
{ .num = 0, .type = SCARLETT_OUTPUTS, .name = "Monitor" },
778
{ .num = 1, .type = SCARLETT_OUTPUTS, .name = "Headphone 1" },
779
{ .num = 2, .type = SCARLETT_OUTPUTS, .name = "Headphone 2" },
780
{ .num = 3, .type = SCARLETT_OUTPUTS, .name = "SPDIF" },
781
{ .num = 1, .type = SCARLETT_SWITCH_IMPEDANCE, .name = NULL},
782
{ .num = 1, .type = SCARLETT_SWITCH_PAD, .name = NULL},
783
{ .num = 2, .type = SCARLETT_SWITCH_IMPEDANCE, .name = NULL},
784
{ .num = 2, .type = SCARLETT_SWITCH_PAD, .name = NULL},
785
{ .num = 3, .type = SCARLETT_SWITCH_PAD, .name = NULL},
786
{ .num = 4, .type = SCARLETT_SWITCH_PAD, .name = NULL},
787
},
788
789
.matrix_mux_init = {
790
8, 9, 10, 11, 12, 13, 14, 15, /* Analog -> 1..8 */
791
18, 19, 20, 21, 22, 23, /* ADAT[1..6] -> 9..14 */
792
16, 17, /* SPDIF -> 15,16 */
793
0, 1 /* PCM[1,2] -> 17,18 */
794
}
795
};
796
797
static const struct scarlett_device_info s18i20_info = {
798
.matrix_in = 18,
799
.matrix_out = 8,
800
.input_len = 18,
801
.output_len = 20,
802
803
.opt_master = {
804
.start = -1,
805
.len = 47,
806
.offsets = {0, 20, 28, 30, 38},
807
.names = NULL
808
},
809
810
.opt_matrix = {
811
.start = -1,
812
.len = 39,
813
.offsets = {0, 20, 28, 30, 38},
814
.names = NULL
815
},
816
817
.num_controls = 10,
818
.controls = {
819
{ .num = 0, .type = SCARLETT_OUTPUTS, .name = "Monitor" },
820
{ .num = 1, .type = SCARLETT_OUTPUTS, .name = "Line 3/4" },
821
{ .num = 2, .type = SCARLETT_OUTPUTS, .name = "Line 5/6" },
822
{ .num = 3, .type = SCARLETT_OUTPUTS, .name = "Line 7/8" },
823
{ .num = 4, .type = SCARLETT_OUTPUTS, .name = "Line 9/10" },
824
{ .num = 5, .type = SCARLETT_OUTPUTS, .name = "SPDIF" },
825
{ .num = 6, .type = SCARLETT_OUTPUTS, .name = "ADAT 1/2" },
826
{ .num = 7, .type = SCARLETT_OUTPUTS, .name = "ADAT 3/4" },
827
{ .num = 8, .type = SCARLETT_OUTPUTS, .name = "ADAT 5/6" },
828
{ .num = 9, .type = SCARLETT_OUTPUTS, .name = "ADAT 7/8" },
829
/*{ .num = 1, .type = SCARLETT_SWITCH_IMPEDANCE, .name = NULL},
830
{ .num = 1, .type = SCARLETT_SWITCH_PAD, .name = NULL},
831
{ .num = 2, .type = SCARLETT_SWITCH_IMPEDANCE, .name = NULL},
832
{ .num = 2, .type = SCARLETT_SWITCH_PAD, .name = NULL},
833
{ .num = 3, .type = SCARLETT_SWITCH_PAD, .name = NULL},
834
{ .num = 4, .type = SCARLETT_SWITCH_PAD, .name = NULL},*/
835
},
836
837
.matrix_mux_init = {
838
20, 21, 22, 23, 24, 25, 26, 27, /* Analog -> 1..8 */
839
30, 31, 32, 33, 34, 35, /* ADAT[1..6] -> 9..14 */
840
28, 29, /* SPDIF -> 15,16 */
841
0, 1 /* PCM[1,2] -> 17,18 */
842
}
843
};
844
845
846
static int scarlett_controls_create_generic(struct usb_mixer_interface *mixer,
847
const struct scarlett_device_info *info)
848
{
849
int i, err;
850
char mx[SNDRV_CTL_ELEM_ID_NAME_MAXLEN];
851
const struct scarlett_mixer_control *ctl;
852
struct usb_mixer_elem_info *elem;
853
854
/* create master switch and playback volume */
855
err = add_new_ctl(mixer, &usb_scarlett_ctl_switch,
856
scarlett_ctl_resume, 0x0a, 0x01, 0,
857
USB_MIXER_S16, 1, "Master Playback Switch", NULL,
858
&elem);
859
if (err < 0)
860
return err;
861
862
err = add_new_ctl(mixer, &usb_scarlett_ctl_master,
863
scarlett_ctl_resume, 0x0a, 0x02, 0,
864
USB_MIXER_S16, 1, "Master Playback Volume", NULL,
865
&elem);
866
if (err < 0)
867
return err;
868
869
/* iterate through controls in info struct and create each one */
870
for (i = 0; i < info->num_controls; i++) {
871
ctl = &info->controls[i];
872
873
switch (ctl->type) {
874
case SCARLETT_OUTPUTS:
875
err = add_output_ctls(mixer, ctl->num, ctl->name, info);
876
if (err < 0)
877
return err;
878
break;
879
case SCARLETT_SWITCH_IMPEDANCE:
880
scnprintf(mx, sizeof(mx),
881
"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
scnprintf(mx, sizeof(mx),
891
"Input %d Pad Switch", ctl->num);
892
err = add_new_ctl(mixer, &usb_scarlett_ctl_enum,
893
scarlett_ctl_enum_resume, 0x01,
894
0x0b, ctl->num, USB_MIXER_S16, 1, mx,
895
&opt_pad, &elem);
896
if (err < 0)
897
return err;
898
break;
899
case SCARLETT_SWITCH_GAIN:
900
scnprintf(mx, sizeof(mx),
901
"Input %d Gain Switch", ctl->num);
902
err = add_new_ctl(mixer, &usb_scarlett_ctl_enum,
903
scarlett_ctl_enum_resume, 0x01,
904
0x08, ctl->num, USB_MIXER_S16, 1, mx,
905
&opt_gain, &elem);
906
if (err < 0)
907
return err;
908
break;
909
}
910
}
911
912
return 0;
913
}
914
915
/*
916
* Create and initialize a mixer for the Focusrite(R) Scarlett
917
*/
918
int snd_scarlett_controls_create(struct usb_mixer_interface *mixer)
919
{
920
int err, i, o;
921
char mx[SNDRV_CTL_ELEM_ID_NAME_MAXLEN];
922
const struct scarlett_device_info *info;
923
struct usb_mixer_elem_info *elem;
924
static char sample_rate_buffer[4] = { '\x80', '\xbb', '\x00', '\x00' };
925
926
/* only use UAC_VERSION_2 */
927
if (!mixer->protocol)
928
return 0;
929
930
switch (mixer->chip->usb_id) {
931
case USB_ID(0x1235, 0x8012):
932
info = &s6i6_info;
933
break;
934
case USB_ID(0x1235, 0x8002):
935
info = &s8i6_info;
936
break;
937
case USB_ID(0x1235, 0x8004):
938
info = &s18i6_info;
939
break;
940
case USB_ID(0x1235, 0x8014):
941
info = &s18i8_info;
942
break;
943
case USB_ID(0x1235, 0x800c):
944
info = &s18i20_info;
945
break;
946
default: /* device not (yet) supported */
947
return -EINVAL;
948
}
949
950
/* generic function to create controls */
951
err = scarlett_controls_create_generic(mixer, info);
952
if (err < 0)
953
return err;
954
955
/* setup matrix controls */
956
for (i = 0; i < info->matrix_in; i++) {
957
snprintf(mx, sizeof(mx), "Matrix %02d Input Playback Route",
958
i+1);
959
err = add_new_ctl(mixer, &usb_scarlett_ctl_dynamic_enum,
960
scarlett_ctl_enum_resume, 0x32,
961
0x06, i, USB_MIXER_S16, 1, mx,
962
&info->opt_matrix, &elem);
963
if (err < 0)
964
return err;
965
966
for (o = 0; o < info->matrix_out; o++) {
967
scnprintf(mx, sizeof(mx),
968
"Matrix %02d Mix %c Playback Volume", i+1,
969
o+'A');
970
err = add_new_ctl(mixer, &usb_scarlett_ctl,
971
scarlett_ctl_resume, 0x3c, 0x00,
972
(i << 3) + (o & 0x07), USB_MIXER_S16,
973
1, mx, NULL, &elem);
974
if (err < 0)
975
return err;
976
977
}
978
}
979
980
for (i = 0; i < info->input_len; i++) {
981
snprintf(mx, sizeof(mx), "Input Source %02d Capture Route",
982
i+1);
983
err = add_new_ctl(mixer, &usb_scarlett_ctl_dynamic_enum,
984
scarlett_ctl_enum_resume, 0x34,
985
0x00, i, USB_MIXER_S16, 1, mx,
986
&info->opt_master, &elem);
987
if (err < 0)
988
return err;
989
}
990
991
/* val_len == 1 needed here */
992
err = add_new_ctl(mixer, &usb_scarlett_ctl_enum,
993
scarlett_ctl_enum_resume, 0x28, 0x01, 0,
994
USB_MIXER_U8, 1, "Sample Clock Source",
995
&opt_clock, &elem);
996
if (err < 0)
997
return err;
998
999
/* val_len == 1 and UAC2_CS_MEM */
1000
err = add_new_ctl(mixer, &usb_scarlett_ctl_sync, NULL, 0x3c, 0x00, 2,
1001
USB_MIXER_U8, 1, "Sample Clock Sync Status",
1002
&opt_sync, &elem);
1003
if (err < 0)
1004
return err;
1005
1006
/* initialize sampling rate to 48000 */
1007
err = snd_usb_ctl_msg(mixer->chip->dev,
1008
usb_sndctrlpipe(mixer->chip->dev, 0), UAC2_CS_CUR,
1009
USB_RECIP_INTERFACE | USB_TYPE_CLASS |
1010
USB_DIR_OUT, 0x0100, snd_usb_ctrl_intf(mixer->hostif) |
1011
(0x29 << 8), sample_rate_buffer, 4);
1012
if (err < 0)
1013
return err;
1014
1015
return err;
1016
}
1017
1018