0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019
0020
0021
0022
0023
0024
0025
0026
0027
0028
0029
0030
0031
0032
0033
0034
0035
0036
0037
0038
0039
0040
0041
0042
0043
0044
0045
0046
0047
0048
0049
0050
0051
0052
0053
0054
0055
0056
0057
0058
0059
0060
0061
0062
0063
0064
0065
0066
0067
0068
0069
0070
0071
0072
0073
0074
0075
0076
0077
0078
0079
0080
0081
0082
0083
0084
0085
0086
0087
0088
0089
0090
0091
0092
0093
0094
0095
0096
0097
0098
0099
0100
0101
0102
0103
0104
0105
0106
0107
0108
0109
0110
0111
0112
0113
0114
0115
0116
0117
0118
0119
0120 #include <linux/slab.h>
0121 #include <linux/usb.h>
0122 #include <linux/usb/audio-v2.h>
0123
0124 #include <sound/core.h>
0125 #include <sound/control.h>
0126 #include <sound/tlv.h>
0127
0128 #include "usbaudio.h"
0129 #include "mixer.h"
0130 #include "helper.h"
0131 #include "power.h"
0132
0133 #include "mixer_scarlett.h"
0134
0135
0136 #define SND_SCARLETT_LEVEL_BIAS 128
0137 #define SND_SCARLETT_MATRIX_IN_MAX 18
0138 #define SND_SCARLETT_CONTROLS_MAX 10
0139 #define SND_SCARLETT_OFFSETS_MAX 5
0140
0141 enum {
0142 SCARLETT_OUTPUTS,
0143 SCARLETT_SWITCH_IMPEDANCE,
0144 SCARLETT_SWITCH_PAD,
0145 SCARLETT_SWITCH_GAIN,
0146 };
0147
0148 enum {
0149 SCARLETT_OFFSET_PCM = 0,
0150 SCARLETT_OFFSET_ANALOG = 1,
0151 SCARLETT_OFFSET_SPDIF = 2,
0152 SCARLETT_OFFSET_ADAT = 3,
0153 SCARLETT_OFFSET_MIX = 4,
0154 };
0155
0156 struct scarlett_mixer_elem_enum_info {
0157 int start;
0158 int len;
0159 int offsets[SND_SCARLETT_OFFSETS_MAX];
0160 char const * const *names;
0161 };
0162
0163 struct scarlett_mixer_control {
0164 unsigned char num;
0165 unsigned char type;
0166 const char *name;
0167 };
0168
0169 struct scarlett_device_info {
0170 int matrix_in;
0171 int matrix_out;
0172 int input_len;
0173 int output_len;
0174
0175 struct scarlett_mixer_elem_enum_info opt_master;
0176 struct scarlett_mixer_elem_enum_info opt_matrix;
0177
0178
0179 int matrix_mux_init[SND_SCARLETT_MATRIX_IN_MAX];
0180
0181 int num_controls;
0182 const struct scarlett_mixer_control controls[SND_SCARLETT_CONTROLS_MAX];
0183 };
0184
0185
0186
0187 static const struct scarlett_mixer_elem_enum_info opt_pad = {
0188 .start = 0,
0189 .len = 2,
0190 .offsets = {},
0191 .names = (char const * const []){
0192 "0dB", "-10dB"
0193 }
0194 };
0195
0196 static const struct scarlett_mixer_elem_enum_info opt_gain = {
0197 .start = 0,
0198 .len = 2,
0199 .offsets = {},
0200 .names = (char const * const []){
0201 "Lo", "Hi"
0202 }
0203 };
0204
0205 static const struct scarlett_mixer_elem_enum_info opt_impedance = {
0206 .start = 0,
0207 .len = 2,
0208 .offsets = {},
0209 .names = (char const * const []){
0210 "Line", "Hi-Z"
0211 }
0212 };
0213
0214 static const struct scarlett_mixer_elem_enum_info opt_clock = {
0215 .start = 1,
0216 .len = 3,
0217 .offsets = {},
0218 .names = (char const * const []){
0219 "Internal", "SPDIF", "ADAT"
0220 }
0221 };
0222
0223 static const struct scarlett_mixer_elem_enum_info opt_sync = {
0224 .start = 0,
0225 .len = 2,
0226 .offsets = {},
0227 .names = (char const * const []){
0228 "No Lock", "Locked"
0229 }
0230 };
0231
0232 static int scarlett_ctl_switch_info(struct snd_kcontrol *kctl,
0233 struct snd_ctl_elem_info *uinfo)
0234 {
0235 struct usb_mixer_elem_info *elem = kctl->private_data;
0236
0237 uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN;
0238 uinfo->count = elem->channels;
0239 uinfo->value.integer.min = 0;
0240 uinfo->value.integer.max = 1;
0241 return 0;
0242 }
0243
0244 static int scarlett_ctl_switch_get(struct snd_kcontrol *kctl,
0245 struct snd_ctl_elem_value *ucontrol)
0246 {
0247 struct usb_mixer_elem_info *elem = kctl->private_data;
0248 int i, err, val;
0249
0250 for (i = 0; i < elem->channels; i++) {
0251 err = snd_usb_get_cur_mix_value(elem, i, i, &val);
0252 if (err < 0)
0253 return err;
0254
0255 val = !val;
0256 ucontrol->value.integer.value[i] = val;
0257 }
0258
0259 return 0;
0260 }
0261
0262 static int scarlett_ctl_switch_put(struct snd_kcontrol *kctl,
0263 struct snd_ctl_elem_value *ucontrol)
0264 {
0265 struct usb_mixer_elem_info *elem = kctl->private_data;
0266 int i, changed = 0;
0267 int err, oval, val;
0268
0269 for (i = 0; i < elem->channels; i++) {
0270 err = snd_usb_get_cur_mix_value(elem, i, i, &oval);
0271 if (err < 0)
0272 return err;
0273
0274 val = ucontrol->value.integer.value[i];
0275 val = !val;
0276 if (oval != val) {
0277 err = snd_usb_set_cur_mix_value(elem, i, i, val);
0278 if (err < 0)
0279 return err;
0280
0281 changed = 1;
0282 }
0283 }
0284
0285 return changed;
0286 }
0287
0288 static int scarlett_ctl_resume(struct usb_mixer_elem_list *list)
0289 {
0290 struct usb_mixer_elem_info *elem = mixer_elem_list_to_info(list);
0291 int i;
0292
0293 for (i = 0; i < elem->channels; i++)
0294 if (elem->cached & (1 << i))
0295 snd_usb_set_cur_mix_value(elem, i, i,
0296 elem->cache_val[i]);
0297 return 0;
0298 }
0299
0300 static int scarlett_ctl_info(struct snd_kcontrol *kctl,
0301 struct snd_ctl_elem_info *uinfo)
0302 {
0303 struct usb_mixer_elem_info *elem = kctl->private_data;
0304
0305 uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
0306 uinfo->count = elem->channels;
0307 uinfo->value.integer.min = 0;
0308 uinfo->value.integer.max = (int)kctl->private_value +
0309 SND_SCARLETT_LEVEL_BIAS;
0310 uinfo->value.integer.step = 1;
0311 return 0;
0312 }
0313
0314 static int scarlett_ctl_get(struct snd_kcontrol *kctl,
0315 struct snd_ctl_elem_value *ucontrol)
0316 {
0317 struct usb_mixer_elem_info *elem = kctl->private_data;
0318 int i, err, val;
0319
0320 for (i = 0; i < elem->channels; i++) {
0321 err = snd_usb_get_cur_mix_value(elem, i, i, &val);
0322 if (err < 0)
0323 return err;
0324
0325 val = clamp(val / 256, -128, (int)kctl->private_value) +
0326 SND_SCARLETT_LEVEL_BIAS;
0327 ucontrol->value.integer.value[i] = val;
0328 }
0329
0330 return 0;
0331 }
0332
0333 static int scarlett_ctl_put(struct snd_kcontrol *kctl,
0334 struct snd_ctl_elem_value *ucontrol)
0335 {
0336 struct usb_mixer_elem_info *elem = kctl->private_data;
0337 int i, changed = 0;
0338 int err, oval, val;
0339
0340 for (i = 0; i < elem->channels; i++) {
0341 err = snd_usb_get_cur_mix_value(elem, i, i, &oval);
0342 if (err < 0)
0343 return err;
0344
0345 val = ucontrol->value.integer.value[i] -
0346 SND_SCARLETT_LEVEL_BIAS;
0347 val = val * 256;
0348 if (oval != val) {
0349 err = snd_usb_set_cur_mix_value(elem, i, i, val);
0350 if (err < 0)
0351 return err;
0352
0353 changed = 1;
0354 }
0355 }
0356
0357 return changed;
0358 }
0359
0360 static void scarlett_generate_name(int i, char *dst, int offsets[])
0361 {
0362 if (i > offsets[SCARLETT_OFFSET_MIX])
0363 sprintf(dst, "Mix %c",
0364 'A'+(i - offsets[SCARLETT_OFFSET_MIX] - 1));
0365 else if (i > offsets[SCARLETT_OFFSET_ADAT])
0366 sprintf(dst, "ADAT %d", i - offsets[SCARLETT_OFFSET_ADAT]);
0367 else if (i > offsets[SCARLETT_OFFSET_SPDIF])
0368 sprintf(dst, "SPDIF %d", i - offsets[SCARLETT_OFFSET_SPDIF]);
0369 else if (i > offsets[SCARLETT_OFFSET_ANALOG])
0370 sprintf(dst, "Analog %d", i - offsets[SCARLETT_OFFSET_ANALOG]);
0371 else if (i > offsets[SCARLETT_OFFSET_PCM])
0372 sprintf(dst, "PCM %d", i - offsets[SCARLETT_OFFSET_PCM]);
0373 else
0374 sprintf(dst, "Off");
0375 }
0376
0377 static int scarlett_ctl_enum_dynamic_info(struct snd_kcontrol *kctl,
0378 struct snd_ctl_elem_info *uinfo)
0379 {
0380 struct usb_mixer_elem_info *elem = kctl->private_data;
0381 struct scarlett_mixer_elem_enum_info *opt = elem->private_data;
0382 unsigned int items = opt->len;
0383
0384 uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
0385 uinfo->count = elem->channels;
0386 uinfo->value.enumerated.items = items;
0387
0388 if (uinfo->value.enumerated.item >= items)
0389 uinfo->value.enumerated.item = items - 1;
0390
0391
0392 scarlett_generate_name(uinfo->value.enumerated.item,
0393 uinfo->value.enumerated.name,
0394 opt->offsets);
0395
0396 return 0;
0397 }
0398
0399 static int scarlett_ctl_enum_info(struct snd_kcontrol *kctl,
0400 struct snd_ctl_elem_info *uinfo)
0401 {
0402 struct usb_mixer_elem_info *elem = kctl->private_data;
0403 struct scarlett_mixer_elem_enum_info *opt = elem->private_data;
0404
0405 return snd_ctl_enum_info(uinfo, elem->channels, opt->len,
0406 (const char * const *)opt->names);
0407 }
0408
0409 static int scarlett_ctl_enum_get(struct snd_kcontrol *kctl,
0410 struct snd_ctl_elem_value *ucontrol)
0411 {
0412 struct usb_mixer_elem_info *elem = kctl->private_data;
0413 struct scarlett_mixer_elem_enum_info *opt = elem->private_data;
0414 int err, val;
0415
0416 err = snd_usb_get_cur_mix_value(elem, 0, 0, &val);
0417 if (err < 0)
0418 return err;
0419
0420 val = clamp(val - opt->start, 0, opt->len-1);
0421
0422 ucontrol->value.enumerated.item[0] = val;
0423
0424 return 0;
0425 }
0426
0427 static int scarlett_ctl_enum_put(struct snd_kcontrol *kctl,
0428 struct snd_ctl_elem_value *ucontrol)
0429 {
0430 struct usb_mixer_elem_info *elem = kctl->private_data;
0431 struct scarlett_mixer_elem_enum_info *opt = elem->private_data;
0432 int err, oval, val;
0433
0434 err = snd_usb_get_cur_mix_value(elem, 0, 0, &oval);
0435 if (err < 0)
0436 return err;
0437
0438 val = ucontrol->value.integer.value[0];
0439 val = val + opt->start;
0440 if (val != oval) {
0441 snd_usb_set_cur_mix_value(elem, 0, 0, val);
0442 return 1;
0443 }
0444 return 0;
0445 }
0446
0447 static int scarlett_ctl_enum_resume(struct usb_mixer_elem_list *list)
0448 {
0449 struct usb_mixer_elem_info *elem = mixer_elem_list_to_info(list);
0450
0451 if (elem->cached)
0452 snd_usb_set_cur_mix_value(elem, 0, 0, *elem->cache_val);
0453 return 0;
0454 }
0455
0456 static int scarlett_ctl_meter_get(struct snd_kcontrol *kctl,
0457 struct snd_ctl_elem_value *ucontrol)
0458 {
0459 struct usb_mixer_elem_info *elem = kctl->private_data;
0460 struct snd_usb_audio *chip = elem->head.mixer->chip;
0461 unsigned char buf[2 * MAX_CHANNELS] = {0, };
0462 int wValue = (elem->control << 8) | elem->idx_off;
0463 int idx = snd_usb_ctrl_intf(chip) | (elem->head.id << 8);
0464 int err;
0465
0466 err = snd_usb_ctl_msg(chip->dev,
0467 usb_rcvctrlpipe(chip->dev, 0),
0468 UAC2_CS_MEM,
0469 USB_RECIP_INTERFACE | USB_TYPE_CLASS |
0470 USB_DIR_IN, wValue, idx, buf, elem->channels);
0471 if (err < 0)
0472 return err;
0473
0474 ucontrol->value.enumerated.item[0] = clamp((int)buf[0], 0, 1);
0475 return 0;
0476 }
0477
0478 static const struct snd_kcontrol_new usb_scarlett_ctl_switch = {
0479 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
0480 .name = "",
0481 .info = scarlett_ctl_switch_info,
0482 .get = scarlett_ctl_switch_get,
0483 .put = scarlett_ctl_switch_put,
0484 };
0485
0486 static const DECLARE_TLV_DB_SCALE(db_scale_scarlett_gain, -12800, 100, 0);
0487
0488 static const struct snd_kcontrol_new usb_scarlett_ctl = {
0489 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
0490 .access = SNDRV_CTL_ELEM_ACCESS_READWRITE |
0491 SNDRV_CTL_ELEM_ACCESS_TLV_READ,
0492 .name = "",
0493 .info = scarlett_ctl_info,
0494 .get = scarlett_ctl_get,
0495 .put = scarlett_ctl_put,
0496 .private_value = 6,
0497 .tlv = { .p = db_scale_scarlett_gain }
0498 };
0499
0500 static const struct snd_kcontrol_new usb_scarlett_ctl_master = {
0501 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
0502 .access = SNDRV_CTL_ELEM_ACCESS_READWRITE |
0503 SNDRV_CTL_ELEM_ACCESS_TLV_READ,
0504 .name = "",
0505 .info = scarlett_ctl_info,
0506 .get = scarlett_ctl_get,
0507 .put = scarlett_ctl_put,
0508 .private_value = 6,
0509 .tlv = { .p = db_scale_scarlett_gain }
0510 };
0511
0512 static const struct snd_kcontrol_new usb_scarlett_ctl_enum = {
0513 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
0514 .name = "",
0515 .info = scarlett_ctl_enum_info,
0516 .get = scarlett_ctl_enum_get,
0517 .put = scarlett_ctl_enum_put,
0518 };
0519
0520 static const struct snd_kcontrol_new usb_scarlett_ctl_dynamic_enum = {
0521 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
0522 .name = "",
0523 .info = scarlett_ctl_enum_dynamic_info,
0524 .get = scarlett_ctl_enum_get,
0525 .put = scarlett_ctl_enum_put,
0526 };
0527
0528 static const struct snd_kcontrol_new usb_scarlett_ctl_sync = {
0529 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
0530 .access = SNDRV_CTL_ELEM_ACCESS_READ | SNDRV_CTL_ELEM_ACCESS_VOLATILE,
0531 .name = "",
0532 .info = scarlett_ctl_enum_info,
0533 .get = scarlett_ctl_meter_get,
0534 };
0535
0536 static int add_new_ctl(struct usb_mixer_interface *mixer,
0537 const struct snd_kcontrol_new *ncontrol,
0538 usb_mixer_elem_resume_func_t resume,
0539 int index, int offset, int num,
0540 int val_type, int channels, const char *name,
0541 const struct scarlett_mixer_elem_enum_info *opt,
0542 struct usb_mixer_elem_info **elem_ret
0543 )
0544 {
0545 struct snd_kcontrol *kctl;
0546 struct usb_mixer_elem_info *elem;
0547 int err;
0548
0549 elem = kzalloc(sizeof(*elem), GFP_KERNEL);
0550 if (!elem)
0551 return -ENOMEM;
0552
0553 elem->head.mixer = mixer;
0554 elem->head.resume = resume;
0555 elem->control = offset;
0556 elem->idx_off = num;
0557 elem->head.id = index;
0558 elem->val_type = val_type;
0559
0560 elem->channels = channels;
0561
0562
0563 elem->private_data = (void *)opt;
0564
0565 kctl = snd_ctl_new1(ncontrol, elem);
0566 if (!kctl) {
0567 kfree(elem);
0568 return -ENOMEM;
0569 }
0570 kctl->private_free = snd_usb_mixer_elem_free;
0571
0572 strscpy(kctl->id.name, name, sizeof(kctl->id.name));
0573
0574 err = snd_usb_mixer_add_control(&elem->head, kctl);
0575 if (err < 0)
0576 return err;
0577
0578 if (elem_ret)
0579 *elem_ret = elem;
0580
0581 return 0;
0582 }
0583
0584 static int add_output_ctls(struct usb_mixer_interface *mixer,
0585 int index, const char *name,
0586 const struct scarlett_device_info *info)
0587 {
0588 int err;
0589 char mx[SNDRV_CTL_ELEM_ID_NAME_MAXLEN];
0590 struct usb_mixer_elem_info *elem;
0591
0592
0593 snprintf(mx, sizeof(mx), "Master %d (%s) Playback Switch",
0594 index + 1, name);
0595 err = add_new_ctl(mixer, &usb_scarlett_ctl_switch,
0596 scarlett_ctl_resume, 0x0a, 0x01,
0597 2*index+1, USB_MIXER_S16, 2, mx, NULL, &elem);
0598 if (err < 0)
0599 return err;
0600
0601
0602 snprintf(mx, sizeof(mx), "Master %d (%s) Playback Volume",
0603 index + 1, name);
0604 err = add_new_ctl(mixer, &usb_scarlett_ctl_master,
0605 scarlett_ctl_resume, 0x0a, 0x02,
0606 2*index+1, USB_MIXER_S16, 2, mx, NULL, &elem);
0607 if (err < 0)
0608 return err;
0609
0610
0611 snprintf(mx, sizeof(mx), "Master %dL (%s) Source Playback Enum",
0612 index + 1, name);
0613 err = add_new_ctl(mixer, &usb_scarlett_ctl_dynamic_enum,
0614 scarlett_ctl_enum_resume, 0x33, 0x00,
0615 2*index, USB_MIXER_S16, 1, mx, &info->opt_master,
0616 &elem);
0617 if (err < 0)
0618 return err;
0619
0620
0621 snprintf(mx, sizeof(mx), "Master %dR (%s) Source Playback Enum",
0622 index + 1, name);
0623 err = add_new_ctl(mixer, &usb_scarlett_ctl_dynamic_enum,
0624 scarlett_ctl_enum_resume, 0x33, 0x00,
0625 2*index+1, USB_MIXER_S16, 1, mx, &info->opt_master,
0626 &elem);
0627 if (err < 0)
0628 return err;
0629
0630 return 0;
0631 }
0632
0633
0634
0635
0636 static const struct scarlett_device_info s6i6_info = {
0637 .matrix_in = 18,
0638 .matrix_out = 8,
0639 .input_len = 6,
0640 .output_len = 6,
0641
0642 .opt_master = {
0643 .start = -1,
0644 .len = 27,
0645 .offsets = {0, 12, 16, 18, 18},
0646 .names = NULL
0647 },
0648
0649 .opt_matrix = {
0650 .start = -1,
0651 .len = 19,
0652 .offsets = {0, 12, 16, 18, 18},
0653 .names = NULL
0654 },
0655
0656 .num_controls = 9,
0657 .controls = {
0658 { .num = 0, .type = SCARLETT_OUTPUTS, .name = "Monitor" },
0659 { .num = 1, .type = SCARLETT_OUTPUTS, .name = "Headphone" },
0660 { .num = 2, .type = SCARLETT_OUTPUTS, .name = "SPDIF" },
0661 { .num = 1, .type = SCARLETT_SWITCH_IMPEDANCE, .name = NULL},
0662 { .num = 1, .type = SCARLETT_SWITCH_PAD, .name = NULL},
0663 { .num = 2, .type = SCARLETT_SWITCH_IMPEDANCE, .name = NULL},
0664 { .num = 2, .type = SCARLETT_SWITCH_PAD, .name = NULL},
0665 { .num = 3, .type = SCARLETT_SWITCH_GAIN, .name = NULL},
0666 { .num = 4, .type = SCARLETT_SWITCH_GAIN, .name = NULL},
0667 },
0668
0669 .matrix_mux_init = {
0670 12, 13, 14, 15,
0671 16, 17,
0672 0, 1, 2, 3, 4, 5, 6, 7,
0673 8, 9, 10, 11
0674 }
0675 };
0676
0677
0678 static const struct scarlett_device_info s8i6_info = {
0679 .matrix_in = 18,
0680 .matrix_out = 6,
0681 .input_len = 8,
0682 .output_len = 6,
0683
0684 .opt_master = {
0685 .start = -1,
0686 .len = 25,
0687 .offsets = {0, 12, 16, 18, 18},
0688 .names = NULL
0689 },
0690
0691 .opt_matrix = {
0692 .start = -1,
0693 .len = 19,
0694 .offsets = {0, 12, 16, 18, 18},
0695 .names = NULL
0696 },
0697
0698 .num_controls = 7,
0699 .controls = {
0700 { .num = 0, .type = SCARLETT_OUTPUTS, .name = "Monitor" },
0701 { .num = 1, .type = SCARLETT_OUTPUTS, .name = "Headphone" },
0702 { .num = 2, .type = SCARLETT_OUTPUTS, .name = "SPDIF" },
0703 { .num = 1, .type = SCARLETT_SWITCH_IMPEDANCE, .name = NULL},
0704 { .num = 2, .type = SCARLETT_SWITCH_IMPEDANCE, .name = NULL},
0705 { .num = 3, .type = SCARLETT_SWITCH_PAD, .name = NULL},
0706 { .num = 4, .type = SCARLETT_SWITCH_PAD, .name = NULL},
0707 },
0708
0709 .matrix_mux_init = {
0710 12, 13, 14, 15,
0711 16, 17,
0712 0, 1, 2, 3, 4, 5, 6, 7,
0713 8, 9, 10, 11
0714 }
0715 };
0716
0717 static const struct scarlett_device_info s18i6_info = {
0718 .matrix_in = 18,
0719 .matrix_out = 6,
0720 .input_len = 18,
0721 .output_len = 6,
0722
0723 .opt_master = {
0724 .start = -1,
0725 .len = 31,
0726 .offsets = {0, 6, 14, 16, 24},
0727 .names = NULL,
0728 },
0729
0730 .opt_matrix = {
0731 .start = -1,
0732 .len = 25,
0733 .offsets = {0, 6, 14, 16, 24},
0734 .names = NULL,
0735 },
0736
0737 .num_controls = 5,
0738 .controls = {
0739 { .num = 0, .type = SCARLETT_OUTPUTS, .name = "Monitor" },
0740 { .num = 1, .type = SCARLETT_OUTPUTS, .name = "Headphone" },
0741 { .num = 2, .type = SCARLETT_OUTPUTS, .name = "SPDIF" },
0742 { .num = 1, .type = SCARLETT_SWITCH_IMPEDANCE, .name = NULL},
0743 { .num = 2, .type = SCARLETT_SWITCH_IMPEDANCE, .name = NULL},
0744 },
0745
0746 .matrix_mux_init = {
0747 6, 7, 8, 9, 10, 11, 12, 13,
0748 16, 17, 18, 19, 20, 21,
0749 14, 15,
0750 0, 1
0751 }
0752 };
0753
0754 static const struct scarlett_device_info s18i8_info = {
0755 .matrix_in = 18,
0756 .matrix_out = 8,
0757 .input_len = 18,
0758 .output_len = 8,
0759
0760 .opt_master = {
0761 .start = -1,
0762 .len = 35,
0763 .offsets = {0, 8, 16, 18, 26},
0764 .names = NULL
0765 },
0766
0767 .opt_matrix = {
0768 .start = -1,
0769 .len = 27,
0770 .offsets = {0, 8, 16, 18, 26},
0771 .names = NULL
0772 },
0773
0774 .num_controls = 10,
0775 .controls = {
0776 { .num = 0, .type = SCARLETT_OUTPUTS, .name = "Monitor" },
0777 { .num = 1, .type = SCARLETT_OUTPUTS, .name = "Headphone 1" },
0778 { .num = 2, .type = SCARLETT_OUTPUTS, .name = "Headphone 2" },
0779 { .num = 3, .type = SCARLETT_OUTPUTS, .name = "SPDIF" },
0780 { .num = 1, .type = SCARLETT_SWITCH_IMPEDANCE, .name = NULL},
0781 { .num = 1, .type = SCARLETT_SWITCH_PAD, .name = NULL},
0782 { .num = 2, .type = SCARLETT_SWITCH_IMPEDANCE, .name = NULL},
0783 { .num = 2, .type = SCARLETT_SWITCH_PAD, .name = NULL},
0784 { .num = 3, .type = SCARLETT_SWITCH_PAD, .name = NULL},
0785 { .num = 4, .type = SCARLETT_SWITCH_PAD, .name = NULL},
0786 },
0787
0788 .matrix_mux_init = {
0789 8, 9, 10, 11, 12, 13, 14, 15,
0790 18, 19, 20, 21, 22, 23,
0791 16, 17,
0792 0, 1
0793 }
0794 };
0795
0796 static const struct scarlett_device_info s18i20_info = {
0797 .matrix_in = 18,
0798 .matrix_out = 8,
0799 .input_len = 18,
0800 .output_len = 20,
0801
0802 .opt_master = {
0803 .start = -1,
0804 .len = 47,
0805 .offsets = {0, 20, 28, 30, 38},
0806 .names = NULL
0807 },
0808
0809 .opt_matrix = {
0810 .start = -1,
0811 .len = 39,
0812 .offsets = {0, 20, 28, 30, 38},
0813 .names = NULL
0814 },
0815
0816 .num_controls = 10,
0817 .controls = {
0818 { .num = 0, .type = SCARLETT_OUTPUTS, .name = "Monitor" },
0819 { .num = 1, .type = SCARLETT_OUTPUTS, .name = "Line 3/4" },
0820 { .num = 2, .type = SCARLETT_OUTPUTS, .name = "Line 5/6" },
0821 { .num = 3, .type = SCARLETT_OUTPUTS, .name = "Line 7/8" },
0822 { .num = 4, .type = SCARLETT_OUTPUTS, .name = "Line 9/10" },
0823 { .num = 5, .type = SCARLETT_OUTPUTS, .name = "SPDIF" },
0824 { .num = 6, .type = SCARLETT_OUTPUTS, .name = "ADAT 1/2" },
0825 { .num = 7, .type = SCARLETT_OUTPUTS, .name = "ADAT 3/4" },
0826 { .num = 8, .type = SCARLETT_OUTPUTS, .name = "ADAT 5/6" },
0827 { .num = 9, .type = SCARLETT_OUTPUTS, .name = "ADAT 7/8" },
0828
0829
0830
0831
0832
0833
0834 },
0835
0836 .matrix_mux_init = {
0837 20, 21, 22, 23, 24, 25, 26, 27,
0838 30, 31, 32, 33, 34, 35,
0839 28, 29,
0840 0, 1
0841 }
0842 };
0843
0844
0845 static int scarlett_controls_create_generic(struct usb_mixer_interface *mixer,
0846 const struct scarlett_device_info *info)
0847 {
0848 int i, err;
0849 char mx[SNDRV_CTL_ELEM_ID_NAME_MAXLEN];
0850 const struct scarlett_mixer_control *ctl;
0851 struct usb_mixer_elem_info *elem;
0852
0853
0854 err = add_new_ctl(mixer, &usb_scarlett_ctl_switch,
0855 scarlett_ctl_resume, 0x0a, 0x01, 0,
0856 USB_MIXER_S16, 1, "Master Playback Switch", NULL,
0857 &elem);
0858 if (err < 0)
0859 return err;
0860
0861 err = add_new_ctl(mixer, &usb_scarlett_ctl_master,
0862 scarlett_ctl_resume, 0x0a, 0x02, 0,
0863 USB_MIXER_S16, 1, "Master Playback Volume", NULL,
0864 &elem);
0865 if (err < 0)
0866 return err;
0867
0868
0869 for (i = 0; i < info->num_controls; i++) {
0870 ctl = &info->controls[i];
0871
0872 switch (ctl->type) {
0873 case SCARLETT_OUTPUTS:
0874 err = add_output_ctls(mixer, ctl->num, ctl->name, info);
0875 if (err < 0)
0876 return err;
0877 break;
0878 case SCARLETT_SWITCH_IMPEDANCE:
0879 sprintf(mx, "Input %d Impedance Switch", ctl->num);
0880 err = add_new_ctl(mixer, &usb_scarlett_ctl_enum,
0881 scarlett_ctl_enum_resume, 0x01,
0882 0x09, ctl->num, USB_MIXER_S16, 1, mx,
0883 &opt_impedance, &elem);
0884 if (err < 0)
0885 return err;
0886 break;
0887 case SCARLETT_SWITCH_PAD:
0888 sprintf(mx, "Input %d Pad Switch", ctl->num);
0889 err = add_new_ctl(mixer, &usb_scarlett_ctl_enum,
0890 scarlett_ctl_enum_resume, 0x01,
0891 0x0b, ctl->num, USB_MIXER_S16, 1, mx,
0892 &opt_pad, &elem);
0893 if (err < 0)
0894 return err;
0895 break;
0896 case SCARLETT_SWITCH_GAIN:
0897 sprintf(mx, "Input %d Gain Switch", ctl->num);
0898 err = add_new_ctl(mixer, &usb_scarlett_ctl_enum,
0899 scarlett_ctl_enum_resume, 0x01,
0900 0x08, ctl->num, USB_MIXER_S16, 1, mx,
0901 &opt_gain, &elem);
0902 if (err < 0)
0903 return err;
0904 break;
0905 }
0906 }
0907
0908 return 0;
0909 }
0910
0911
0912
0913
0914 int snd_scarlett_controls_create(struct usb_mixer_interface *mixer)
0915 {
0916 int err, i, o;
0917 char mx[SNDRV_CTL_ELEM_ID_NAME_MAXLEN];
0918 const struct scarlett_device_info *info;
0919 struct usb_mixer_elem_info *elem;
0920 static char sample_rate_buffer[4] = { '\x80', '\xbb', '\x00', '\x00' };
0921
0922
0923 if (!mixer->protocol)
0924 return 0;
0925
0926 switch (mixer->chip->usb_id) {
0927 case USB_ID(0x1235, 0x8012):
0928 info = &s6i6_info;
0929 break;
0930 case USB_ID(0x1235, 0x8002):
0931 info = &s8i6_info;
0932 break;
0933 case USB_ID(0x1235, 0x8004):
0934 info = &s18i6_info;
0935 break;
0936 case USB_ID(0x1235, 0x8014):
0937 info = &s18i8_info;
0938 break;
0939 case USB_ID(0x1235, 0x800c):
0940 info = &s18i20_info;
0941 break;
0942 default:
0943 return -EINVAL;
0944 }
0945
0946
0947 err = scarlett_controls_create_generic(mixer, info);
0948 if (err < 0)
0949 return err;
0950
0951
0952 for (i = 0; i < info->matrix_in; i++) {
0953 snprintf(mx, sizeof(mx), "Matrix %02d Input Playback Route",
0954 i+1);
0955 err = add_new_ctl(mixer, &usb_scarlett_ctl_dynamic_enum,
0956 scarlett_ctl_enum_resume, 0x32,
0957 0x06, i, USB_MIXER_S16, 1, mx,
0958 &info->opt_matrix, &elem);
0959 if (err < 0)
0960 return err;
0961
0962 for (o = 0; o < info->matrix_out; o++) {
0963 sprintf(mx, "Matrix %02d Mix %c Playback Volume", i+1,
0964 o+'A');
0965 err = add_new_ctl(mixer, &usb_scarlett_ctl,
0966 scarlett_ctl_resume, 0x3c, 0x00,
0967 (i << 3) + (o & 0x07), USB_MIXER_S16,
0968 1, mx, NULL, &elem);
0969 if (err < 0)
0970 return err;
0971
0972 }
0973 }
0974
0975 for (i = 0; i < info->input_len; i++) {
0976 snprintf(mx, sizeof(mx), "Input Source %02d Capture Route",
0977 i+1);
0978 err = add_new_ctl(mixer, &usb_scarlett_ctl_dynamic_enum,
0979 scarlett_ctl_enum_resume, 0x34,
0980 0x00, i, USB_MIXER_S16, 1, mx,
0981 &info->opt_master, &elem);
0982 if (err < 0)
0983 return err;
0984 }
0985
0986
0987 err = add_new_ctl(mixer, &usb_scarlett_ctl_enum,
0988 scarlett_ctl_enum_resume, 0x28, 0x01, 0,
0989 USB_MIXER_U8, 1, "Sample Clock Source",
0990 &opt_clock, &elem);
0991 if (err < 0)
0992 return err;
0993
0994
0995 err = add_new_ctl(mixer, &usb_scarlett_ctl_sync, NULL, 0x3c, 0x00, 2,
0996 USB_MIXER_U8, 1, "Sample Clock Sync Status",
0997 &opt_sync, &elem);
0998 if (err < 0)
0999 return err;
1000
1001
1002 err = snd_usb_ctl_msg(mixer->chip->dev,
1003 usb_sndctrlpipe(mixer->chip->dev, 0), UAC2_CS_CUR,
1004 USB_RECIP_INTERFACE | USB_TYPE_CLASS |
1005 USB_DIR_OUT, 0x0100, snd_usb_ctrl_intf(mixer->chip) |
1006 (0x29 << 8), sample_rate_buffer, 4);
1007 if (err < 0)
1008 return err;
1009
1010 return err;
1011 }